来源:http://poj.org/problem?id=1861
题意:有一些公司,公司之间需要连接起来。给出了哪些公司可以连接以及连接边的长度。求最小生成树中最大的边,以及最小生成树的边数,以及输出一颗可行的最小生成树。
思路:基本上就是裸的kruskal了。可以水之。
代码:
#include <iostream> #include <cstdio> #include <string.h> #include <algorithm> using namespace std; const int N = 1010, M = 15010; struct edge{ int x,y,value; }ee[M]; struct solve{ int lp,rp; }ss[M]; int father[N],numedge,n,m,cnt,numsolve; bool cmp(edge a,edge b){ return a.value < b.value; } int find(int x){ if(father[x] == x) return father[x]; return find(father[x]); } bool Union_Set(int x,int y){ int lp = find(x); int rp = find(y); if(lp == rp) return false; else{ father[lp] = rp; return true; } } int kruskal(){ cnt = 0; int mmax = 0; numsolve = 0; for(int i = 1; i <= n; ++i) father[i] = i; for(int i = 0; i < numedge; ++i){ int lx = ee[i].x; int rx = ee[i].y; if(Union_Set(lx,rx)){ cnt++; if(mmax < ee[i].value) mmax = ee[i].value; ss[numsolve].lp = lx; ss[numsolve].rp = rx; numsolve++; } } return mmax; } int main(){ while(scanf("%d%d",&n,&m) != EOF){ int x,y,z; numedge = 0; while(m--){ scanf("%d%d%d",&x,&y,&z); ee[numedge].x = x; ee[numedge].y = y; ee[numedge].value = z; numedge++; } sort(ee,ee+numedge,cmp); int ans = kruskal(); printf("%d\n",ans); printf("%d\n",cnt); for(int i = 0; i < numsolve; ++i) printf("%d %d\n",ss[i].lp,ss[i].rp); } return 0; }