题目描述
输入一个连通无向网络,输出它的最小生成树的权值和
输入
输入文件第一行为n和m(n,m<=20),表示n个顶点和m条边,接下来m行,每行vi,vj,k(0 < k <=100),表示vi到vj有条边,而且权值是k
输出
输出文件仅一行,为最小生成树的权值和
输入样例
4 5
1 2 2
1 3 1
2 3 5
3 4 2
4 1 3
输出样例
5
裸裸的模板题,就当练代码了。
#include<iostream> #include<cstdio> #include<algorithm> using namespace std; const int MAXN=101; int v[MAXN],w[MAXN],r[MAXN],e[MAXN],f[MAXN];//v,w表示这条边的两个端点,r表示边的序号,f表示父节点,e表示边权。 int n,m; int find(int root){//查找根结点并路径压缩 int son,temp; son=root; while(f[root]!=root) root=f[root]; while(f[son]!=root){ temp=f[son]; f[son]=root; son=temp; } return root; } bool cmp(const int a,const int b){//按边权从小到大排序 return e[a]<e[b]; } void Kruscal(){ int ans=0; for(int i=1;i<=m;i++)//初始化边的序号 r[i]=i; for(int i=1;i<=n;i++)//初始化父节点 f[i]=i; sort(r+1,r+m+1,cmp); for(int i=1;i<=m;i++){ int s=r[i]; int a=find(v[s]); int b=find(w[s]); if(a!=b){//如果端点不在同一集合的话就加入 f[a]=b;//合并2个集合 ans+=e[s];//加上边的权值 } } cout<<ans; } int main(){ cin>>n>>m; for(int i=1;i<=m;i++) { int a,b,c; cin>>a>>b>>c; v[i]=a; w[i]=b; e[i]=c; } Kruscal(); }