我个人比较喜欢Kruskal算法,所以就把这个方法写了一下,但过不了洛谷,70分。
思路是先全读入,再排序,一条一条加边。运用并查集。
#include<iostream> #include<cstdio> #include<algorithm> using namespace std; struct s{ int h; int t; int w; }; int fa[30000]; bool cmp(s a,s b) { return a.w < b.w; } int find(int a) { if(fa[a] != a) //不是while fa[a] = find(fa[a]); return fa[a]; } void un(int a,int b) { a = find(a); b = find(b); if(a != b) fa[b] = a; } bool judge(int a,int b) { a = find(a); b = find(b); if(a != b) return false; else return true; } s side[10001]; int m,n,k,tot = 0,num = 1; int main() { cin>>n>>k; for(int i = 1;i <= n;i++) { fa[i] = i; } for(int i = 1;i <= k;i++) { cin>>side[i].h>>side[i].t>>side[i].w; //tot += side[i].w; } sort(side + 1,side + k + 1,cmp); tot = 0; for(int i = 1;i <= k;i++) { if(judge(side[i].h,side[i].t) == false) { un(side[i].h,side[i].t); tot += side[i].w; num++; } if(num == n) break; } cout<<tot<<endl; return 0; } /* 5 5 1 2 8 1 3 1 1 5 3 2 4 5 3 4 2 */
再加一个并查集的板子,日后备用。
#include<iostream> using namespace std; int fa[100],m,n,x,y,z; int find(int a) { if(fa[a] != a) fa[a] = find(fa[a]); return fa[a]; } bool judge(int a,int b) { a = find(a); b = find(b); if(a != b) return false; else return true; } void un(int a,int b) { a = find(a); b = find(b); if(a != b) fa[b] = a; } int main() { cin>>m>>n; for(int i = 0;i < m;i++) fa[i] = i; for(int i = 0;i <n;i++) { cin>>x>>y>>z; if(x == 1) { if(judge(y,z) == false) un(y,z); } else { if(judge(y,z) == true) cout<<"Yeah"<<endl; else cout<<"No,opps"<<endl; } } return 0; }