Sicily 1090 Highways(Kruskal最小生成树)

//求最小生成树中的最大边 //第一次写Kruskal算法,感谢JSH同学的指点 //并查集的优越性,平摊后只需要O(1)的时间即可获取结果 //求最小生成树时时刻注意边数和结点数是不同的,不要混淆,因为弄混了WA了3次 #include<iostream> #include<cstdlib> #include<algorithm> using namespace std; int G[505][505]; int n,t,_max; struct edge//边集结构体 { int u; int v; int w; }E[130000]; int fa[505];//父亲指针数组 bool cmp(edge a,edge b) { return a.w < b.w; } int getfather(int x)//返回父亲结点 { return fa[x] == x ? x : fa[x] = getfather(fa[x]); } int Kruskal(int p) { for(int i = 1;i <= n;++i)//初始化父亲指针,一开始每个点的父亲都是自己 fa[i] = i; for(int i = 0;i < p;++i) { int x = getfather(E[i].u); int y = getfather(E[i].v); if(x != y) { if(E[i].w > _max) _max = E[i].w; fa[x] = y;//合并两颗树,只需把y当做x的父亲就可以了 } } return _max; } int main() { //freopen("in.txt","r",stdin); scanf("%d",&t); while(t--) { scanf("%d",&n); _max = -1; for(int i = 1;i <= n;++i) for(int j = 1;j <= n;++j) scanf("%d",&G[i][j]);//读图 //从邻接矩阵提取边的信息 int e = 0;//记录边数 for(int i = 1;i <= n-1;++i) { for(int j = i+1;j <= n;++j) { E[e].u = i; E[e].v = j; E[e++].w = G[i][j]; } } sort(E,E+e,cmp);//将边从小到大排序 printf("%d/n",Kruskal(e)); if(t != 0) printf("/n");//格式!case之间有空格,最后没有,PE了一次! } return 0; } 

你可能感兴趣的:(Sicily 1090 Highways(Kruskal最小生成树))