#include<cstdio> #include<iostream> #include<algorithm> #define maxn 101 #define maxe 10001 using namespace std; struct line { int a,b; //边的2个顶点 int len; //边的长度 }; bool compare(line a,line b) { return a.len<b.len; } line edge[maxe];//保存所有边的信息 int father[maxn];//father存i的父亲节点 int n,e;//n为顶点数,e为边数 void init()//初始化 { int i; scanf("%d%d",&n,&e); for(i=1;i<=e;i++) scanf("%d%d%d",&edge[i].a,edge[i].b,edge[i].len);//读入图的信息 for(i=1;i<=n;i++)father[i]=i;//初始化并查集 sort(edge+1,edge+1+e,compare);//使用快速排序将边按权值从小到大排列 } int getfather(int x)//并查集,用来判断2个顶点是否属于同一个生成树 { if(x!=father[x])father[x]=getfather(father[x]); return father[x]; } void kruskal() { int x,y,k,cnt,tot;//k为当前边的编号,tot统计最小生成树的边权总和 //cnt统计进行了几次合并。n-1次合并后就得到最小生成树 cnt=0;k=0; tot=0; while(cnt<n-1)//n个点构成的生成树总共只有n-1条边 { k++; x=getfather(edge[k].a); y=getfather(edge[k].b); if(x!=y) { father[x]=y; //合并到一个生成树 tot=tot+edge[k].len; cnt++; } } printf("%d\n",tot); } int main() { init(); kruskal(); return 0; }
以下附上结构体版本,以<span style="font-family: Simsun; text-align: -webkit-center;"><span style="font-size:12px;">【USACO3.1.1】Agri-Net最短网络为例:</span></span>
<span style="font-family: Simsun; text-align: -webkit-center;"><span style="font-size:12px;"></span></span><pre name="code" class="cpp">#include<cstdio> #include<algorithm> #include<vector> using namespace std; const int maxn=1005; struct Edge{ int from,to,w; Edge(int from,int to,int w):from(from),to(to),w(w){} bool operator < (const Edge s)const{ return w<s.w; } }; struct krusckal{ int n,tot; int father[maxn]; vector<int>path; vector<Edge> edge; int getfather(int x){ return x==father[x]?x:father[x]=getfather(father[x]); } void init(int n){ this->n=n; path.clear(); edge.clear(); for(int i=1;i<=n;i++)father[i]=i; } void add_edge(int from,int to,int w){ edge.push_back(Edge(from,to,w)); } bool solve(){ int x,y,k=0,cnt=0; tot=0; sort(edge.begin(),edge.end()); while(cnt<n&&k<edge.size()){ x=getfather(edge[k].from); y=getfather(edge[k].to); if(x!=y){ father[x]=y; tot+=edge[k].w; cnt++; path.push_back(k); } k++; } if(cnt==n-1)return true; return false; } }; int main(){ int n,i,j,x; krusckal solver; scanf("%d",&n); solver.init(n); for(i=1;i<=n;i++) for(j=1;j<=n;j++){ scanf("%d",&x); solver.add_edge(i,j,x); } solver.solve(); printf("%d",solver.tot); }
<span style="color: rgb(0, 0, 255); font-family: Simsun; text-align: -webkit-center;"><span style="font-size:12px;"> </span></span>
<span style="color: rgb(0, 0, 255); font-family: Simsun; text-align: -webkit-center;"><span style="font-size:12px;"></span></span><pre name="code" class="cpp">