poj 1861 Network[ MST ]
题目连接:http://poj.org/problem?id=1861
题目描述:
Andrew是某个公司的系统管理员,他计划为他的公司搭建一个新的网络。在新的网络中,有N个集线器,集线器之间可以通过网线连接。由于公司职员需要通过集线器访问整个网络,因此每个集线器必须能通过网线连接其他集线器(可以通过其他中间集线器来连接)。
由于有不同长度的网线可供选择,而且网线越短越便宜,因此Andres所设计的方案必须确保最长的单跟网线的长度在所有方案中是最小的。并不是所有集线器之间都可以直接连接,但Andrew会提供集线器之间所有可能的连接。
试帮助Andrew设计一个网络,连接所有的集线器并满足前面的条件。
输入描述:
输入文件中包含多个测试数据。每个测试数据的第1行为两个整数:N和M,N表示网络中集线器的数目,2《=N《=1000,集线器的编号从1~N;M表示集线器之间连接的数目,1《=M《=15000.接下来M行描述了M对连接的信息,每对连接的格式为:所连接的两个集线器的编号,连接这两个集线器所需要网线的长度,长度不超过10^6的正整数。两个集线器之间至多有一对连接;每个集线器不能与自己连接。测试数据保证网络是连通的。
测试一直到文件结束。
输出描述:
对输入文件中的每个测试数据,首先输出连接方案中最长的单跟网线的长度(必须使得这个值取到最小);然后输出设计方案:
先输入一个整数p,代表所使用的网线数目;然后输出p对顶点,表示每根网线所连接的集线器编号,整数之间用空格或换行符隔开。
思路:最小生成数
#include<stdio.h> #include<string.h> #include<stdlib.h> struct node { int u, v, w; }; struct node edge[15002]; struct node ans[15002]; int n, m, max_edge; int parent[1002]; int cmp(const void *a, const void *b) { struct node c = *(struct node*)a; struct node d = *(struct node*)b; return c.w - d.w; } int Find(int x) { int s = x; while( parent[s] >= 0) { s = parent[s]; } while( s != x ) { int tmp = parent[x]; parent[x] = s; x = tmp; } return s; } int Union(int R1, int R2) { int r1 = Find(R1); int r2 = Find(R2); if( r1 == r2 ) return 0; int tmp = parent[r1] + parent[r2]; if(parent[r1] < parent[r2]) { parent[r2] = r1; parent[r1] = tmp; } else { parent[r1] = r2; parent[r2] = tmp; } return 1; } int Kruskal() { int t = 0; for(int i = 0; i < m; i++) { if( Union(edge[i].u, edge[i].v) ) { ans[t].u = edge[i].u; ans[t].v = edge[i].v; ans[t].w = edge[i].w; max_edge = max_edge > ans[t].w ? max_edge : ans[t].w; t++; } if( t >= n-1 ) break; } return t; } int main() { while(scanf("%d %d", &n, &m) != EOF) { for(int i = 0; i < m; i++) { scanf("%d %d %d", &edge[i].u, &edge[i].v, &edge[i].w); } qsort(edge, m, sizeof(struct node), cmp); memset(parent, -1, sizeof(parent)); max_edge = -1; int tot = Kruskal(); printf("%d\n", max_edge); printf("%d\n", tot); for(int i = 0; i < tot; i++) { printf("%d %d\n", ans[i].u, ans[i].v); } } return 0; }