看了他们的题解感觉很震惊,为什么要用kruskal,这题要用到最小生成树吗???
38行短短的程序就可以了,我觉得学习不是一种套用,套自己学的,而且题解很大一部分都是kruskal。
个人认为自己的程序比他们快。
1 #include<bits/stdc++.h> 2 using namespace std; 3 struct node{ 4 int x,y,z; 5 }q[100010]; 6 int fa[100010],num[100010]; 7 int n,m; 8 bool f; 9 int w_comp(const node a,const node b){ 10 return a.z<b.z; 11 } 12 int get(int x){ 13 if (x==fa[x]) return x; 14 return fa[x]=get(fa[x]); 15 } 16 void add(int x,int y){ 17 fa[get(y)]=get(x); 18 } 19 int main(){ 20 cin>>n>>m; 21 f=false; 22 for (int i=1;i<=n;i++) { 23 fa[i]=i; 24 num[i]=1;//初始化,每一个集合中都有一个元素,就是它自己 25 } 26 for (int i=1;i<=m;i++) 27 cin>>q[i].x>>q[i].y>>q[i].z; 28 sort(q+1,q+m+1,w_comp);//排序,结构体的排序在第一篇blog中已经讲到。由于只要联通了就可以不用再找,所以我们从时间少的开始加上边 29 for (int i=1;i<=m;i++){ 30 if (get(q[i].x)!=get(q[i].y)){//如果在一个集合再加就没有必要了,因为之前肯定加了一次,不然不会在一个集合 31 num[get(q[i].x)]+=num[get(q[i].y)]; 32 num[get(q[i].y)]=0;//其实这边用了get5次,记录一下的话只要3次时间复杂度又降了些许 33 } 34 if (num[get(q[i].x)]==n){cout<<q[i].z;return 0;} 35 add(q[i].x,q[i].y);//并查集部分需要的可以看我之前的blog 36 } 37 cout<<-1<<endl; 38 }
这道题的关键之处就在于如何记录你的集合的元素。经过思考我发现在主程序中增加是很好的一种选择。