题目地址: http://acm.hdu.edu.cn/showproblem.php?pid=1879
标准的最小生成树,不用什么其他思想就可以AC,直接上代码。
代码如下:注释很清晰相信都能懂
#include <iostream> #include <cstdio> #include <cstdlib> #include <cmath> #include <cstring> #include <string> #include <algorithm> #include <vector> #include <set> #include <map> #include <queue> #include <stack> using namespace std; /* freopen("input.txt","r",stdin); freopen("output.txt","w",stdout); */ int n,m;//n个点,总共有m跳边,单向边 int parent[105];//父亲节点 struct se { int x,y,w; }edge[5055]; bool emp(se a,se b) { return a.w<b.w; } void UFset() { for(int i=0;i<=n;i++) parent[i]=i; } int find(int x) { int r=x; while(x!=parent[x]) x=parent[x]; while(r!=x)//剪枝优化 { int j=parent[r]; parent[r]=x; r=j; } return x; } void Kruskal() { int i,j,count=0,sum=0; UFset();//初始化父亲节点 for(i=0;i<m;i++) { int fx=find(edge[i].x);//x的根节点 int fy=find(edge[i].y);//y的根节点 if(fx!=fy)//两个根节点不相同代表不在一个集合里面,就合并 { count++; parent[fx]=fy; sum+=edge[i].w; if(count==n-1) break; } } printf("%d\n",sum); } int main() { int i,j; while(cin>>n,n) { m=0; int sum=n*(n-1)/2; for(i=1;i<=sum;i++) { int a,b,t,d; scanf("%d%d%d%d",&a,&b,&t,&d); if(a>b)//保证a<b swap(a,b); edge[m].x=a; edge[m].y=b; if(d==0) edge[m].w=t; else//已经建成的w置为0 edge[m].w=0; m++; } sort(edge,edge+m,emp);//边从小到大排序 Kruskal(); } return 520; }