施工中......
先在这里给出我的并查集模板
以下为比较常用的
路径压缩
int f[MAXN],n,m; void clean() { for(int i=1; i<=n; i++) f[i]=i; } int find(int x) { if(x!=f[x]) f[x]=find(f[x]); return f[x]; } void add(int x,int y) { int fx=find(x),fy=find(y); if(fx!=fy) f[fx]=fy; }
带权
int find(int x) { if(x==f[x]) return x; else { int t=f[x]; f[x]=find(f[x]); d[x]+=d[t]; return f[x]; } } void add(int x,int y,int v) { int fx=find(x),fy=find(y); if(fx!=fy) { f[fx]=fy; d[fx]=-d[x]+d[y]+v; } }
课后题目
A 宝可梦对决
思路:套用带权并查集 把权值%3 最后判断克制关系
实现代码(写的比较早 仅供参考)
#include<iostream> #include<stdio.h> using namespace std; int f[100000],d[100000]; int find(int x){ if(x!=f[x]) { int t=f[x]; f[x]=find(f[x]); d[x]=(d[x]+d[t])%3; } return f[x]; } void add(int x,int y){ int fx=find(x),fy=find(y); if(fx!=fy){ f[fx]=fy; d[fx]=(d[y]-d[x]+1)%3; } } int main(){ int n,t,i,x,y; scanf("%d %d",&n,&t); for(i=1;i<=n;i++) f[i]=i; while(t--){ scanf("%d %d",&x,&y); add(x,y); } scanf("%d %d",&x,&y); find(x);find(y); //for(i=1;i<=n;i++) //cout<<d[i]<<endl; if(d[x]-d[y]==1||d[x]-d[y]==-2) cout<<"wait for me, my dear!"<<endl; else if(d[x]==d[y]) cout<<"can I win the game?"<<endl; else cout<<"change! change! change!"<<endl; }View Code
B 合根植物
思路:用并查集合起来,然后算根的个数就行了
#include<bits/stdc++.h> #define close std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0) using namespace std; typedef long long ll; const ll MAXN = 2e6+7; const ll mod = 1e9+7; const ll inf = 0x3f3f3f3f; int f[MAXN],n,m; void clean() { for(int i=1; i<=(n*m); i++) f[i]=i; } int find(int x) { if(x!=f[x]) f[x]=find(f[x]); return f[x]; } void add(int x,int y) { int fx=find(x),fy=find(y); if(fx!=fy) f[fx]=fy; } void solve(){ cin>>n>>m; clean(); int q;cin>>q; while(q--){ int u,v;cin>>u>>v; add(u,v); } int ans=0; for(int i=1;i<=n*m;i++){ if(find(i)==i) ans++; } cout<<ans; } signed main(){ solve(); }View Code
C 修复公路
建议学完最小生成树再来
思路:每次选最快的合并,合并到不能合并,然后输出最后一个合并的时间
#include<bits/stdc++.h> #define close std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0) using namespace std; typedef long long ll; const ll MAXN = 3e5+7; const ll mod = 1e9+7; const ll inf = 0x3f3f3f3f; int f[MAXN],n,m; struct node{ int u,v,w; }N[MAXN]; bool bj(node a,node b){ return a.w<b.w; } void clean() { for(int i=1; i<=n; i++) f[i]=i; } int find(int x) { if(x!=f[x]) f[x]=find(f[x]); return f[x]; } void add(int x,int y) { int fx=find(x),fy=find(y); if(fx!=fy) f[fx]=fy; } void solve(){ cin>>n>>m; clean(); for(int i=1;i<=m;i++){ cin>>N[i].u>>N[i].v>>N[i].w; } sort(N+1,N+1+m,bj); int ans=0,cnt=0; for(int i=1;i<=m;i++){ int u=N[i].u,v=N[i].v,w=N[i].w; if(find(u)!=find(v)){ add(u,v); ans=max(ans,w); } } for(int i=1;i<=n;i++){ if(find(i)==i) cnt++; } if(cnt>1) cout<<"-1"; else cout<<ans; } signed main(){ solve(); }View Code
标签:const,补全,int,fy,讲课,查集,find,fx,ll From: https://www.cnblogs.com/xishuiw/p/17584555.html