14 条题解
-
6
使用 Kruskal 算法解决。
主要思路:把边以边权从小到大排序。接下来从头开始枚举边。如果边会使得后面的图一定不是树(即出现环),则跳过。如果总共已经 条边,则结束。如果所有枚举完后不到 条边,则返回不行(此题没有)。
那么如何判断是否有环?最好的方法就是使用优化的并查集。
代码:
#include<bits/stdc++.h> using namespace std; #define int long long int m,n,cnt,sum; int fa[100009]; struct edge{ int w; int u,v; }; edge e[200009]; bool cmp(edge x,edge y){ return x.w<y.w; } void init(){ cin>>n>>m; for(int i=1;i<=m;i++) cin>>e[i].u>>e[i].v>>e[i].w; for(int i=1;i<=n;i++) fa[i]=i; } int anc(int k){ if(fa[k]==k) return k; else return fa[k]=anc(fa[k]); } void relate(int x,int y){ if(x<y) swap(x,y); fa[anc(y)]=anc(x); } signed main(){ init(); sort(e+1,e+m+1,cmp); for(int i=1;i<=m;i++){ if(anc(e[i].u)!=anc(e[i].v)){ cnt++; relate(e[i].u,e[i].v); sum+=e[i].w; } if(cnt==n-1) break; } if(cnt!=n-1) cout<<"No solution"; else cout<<sum; return 0; }
信息
- ID
- 91
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 3
- 标签
- 递交数
- 871
- 已通过
- 286
- 上传者