并查集及其应用
题目后续补吧,主要解决问题;
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N=1e5+5; 4 int fa[N]; 5 int find_fa(int x){ 6 return fa[x]=(x==fa[x])?x:find_fa(fa[x]);//路径压缩 7 } 8 void merge(int x,int y) 9 { 10 int fx=find_fa(x),fy=find_fa(y);//这里是随机合并,也可以用按秩合并; 11 fa[fy]=fx; 12 } 13 int main() 14 { 15 //1.处理无向图的连通分量 16 //2.处理最小生成树,边从小到大选n-1条边,如果一条边的两个点不在同一集合就加边 17 //证明,最小的n-1条边能型形成n个点的数,如果存在一条小边成环,则去说明去到较大的留下更小的会从u->v更优; 18 return 0; 19 }
洛谷模板题
P3366 【模板】最小生成树
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef vector<int> vec; 4 const int N=5e3+5; 5 int fa[N]; 6 int n,m; 7 struct cmp 8 { 9 bool operator()(vec &a,vec &b) 10 { 11 return a[2]>b[2]; 12 } 13 }; 14 int fd(int x) 15 { 16 return fa[x]=(x==fa[x])?x:fd(fa[x]); 17 } 18 void merge(int x,int y) 19 { 20 int fx=fd(x),fy=fd(y); 21 fa[fy]=fx; 22 } 23 24 int main() 25 { 26 scanf("%d%d",&n,&m); 27 priority_queue<vec,vector<vec>,cmp>q; 28 for(int i=1;i<=n;i++)fa[i]=i; 29 for(int i=1;i<=m;i++) 30 { 31 int u,v,w; 32 scanf("%d%d%d",&u,&v,&w); 33 vec tmp{u,v,w}; 34 q.push(tmp); 35 } 36 int cnt=0,ans=0; 37 while(q.size()) 38 { 39 if(cnt==n-1)break; 40 auto p=q.top(); 41 q.pop(); 42 int u=p[0],v=p[1],w=p[2]; 43 if(fd(u)!=fd(v)) 44 { 45 merge(u,v); 46 ans+=w; 47 cnt++; 48 } 49 } 50 int root=fd(1),ok=true; 51 for(int i=1;i<=n;i++)if(fd(i)!=root)ok=false; 52 if(!ok)printf("%s\n","orz"); 53 else printf("%d\n",ans); 54 return 0; 55 }

浙公网安备 33010602011771号