-
题目描述:
-
现在有孤岛n个,孤岛从1开始标序一直到n,有道路m条(道路是双向的,如果有多条道路连通岛屿i,j则选择最短的那条),请你求出能够让所有孤岛都连通的最小道路总长度。
-
输入:
-
数据有多组输入。
每组第一行输入n(1<=n<=1000),m(0<=m<=10000)。
接着m行,每行输入一条道路i j d(0<=d<=1000),(i,j表示岛屿序号,d表示道路长度)。
-
输出:
-
对每组输入输出一行,如果能连通,输出能连通所有岛屿的最小道路长度,否则请输出字符串"no"。
-
样例输入:
-
3 5 1 2 2 1 2 1 2 3 5 1 3 3 3 1 2 4 2 1 2 3 3 4 1
-
样例输出:
-
3 no
-
#include <stdio.h> #include <stdlib.h> struct path { int u, v, len; }; #define MAX 1005 int father[MAX]; int rank[MAX]; int compare(const void *p, const void *q) { const struct path *a = p; const struct path *b = q; return a->len - b->len; } int find_set(int x) { int root; if (x == father[x]) { return x; } root = find_set(father[x]); father[x] = root; return root; } int main() { int i, n, m, u, v, mst, count; struct path *paths; while (scanf("%d %d", &n, &m) != EOF) { // 初始化并查集数组 for (i = 1; i <= n; i ++) { father[i] = i; rank[i] = 1; } paths = (struct path *)malloc(sizeof(struct path) * m); // 接收边 for (i = 0; i < m; i ++) { scanf("%d %d %d", &paths[i].u, &paths[i].v, &paths[i].len); } qsort(paths, m, sizeof(paths[0]), compare); // kruskal求最小生成树 for (i = mst = count = 0; i < m; i ++) { u = find_set(paths[i].u); v = find_set(paths[i].v); if (u != v) { if (rank[u] < rank[v]) { father[u] = v; } else { father[v] = u; if (rank[u] == rank[v]) { rank[v] ++; } } mst += paths[i].len; // 记录次数,判断连通性 count ++; } } // 打印输出 if (count < n - 1) { printf("no\n"); }else { printf("%d\n", mst); } free(paths); } return 0; }
-
<pre name="code" class="cpp">#include <stdio.h> #include <stdlib.h> #define MAX_N 1001 #define MAX_M 10001 int Tree[MAX_N]; typedef struct{ int s; int e; int dis; }Edge; Edge edges[MAX_M]; int Tree[MAX_N]; void Initial(int n) { int i; for(i = 1; i <= n; i++) Tree[i] = -1; } int findRoot(int x) { if(Tree[x] == -1) return x; else { Tree[x] = findRoot(Tree[x]); return Tree[x]; } } int cmp(const void *a, const void *b) { return (*((Edge *)a)).dis- (*((Edge *)b)).dis; } int main() { int n, m; int i, result; while(scanf("%d%d", &n, &m) != EOF) { result = 0; Initial(n); for(i = 1; i <= m; i++) { scanf("%d%d%d", &edges[i].s, &edges[i].e, &edges[i].dis); } qsort(edges + 1, m, sizeof(Edge), cmp); //根据dis把edges数组从小到大排序 int cnt = 0; for(i = 1; i <= m; i++) { int p = findRoot(edges[i].s); int q = findRoot(edges[i].e); if(p != q) { Tree[q] = p; result += edges[i].dis; cnt ++; //cnt统计边数,每加入一条边,cnt+1 if(cnt == n-1) break; } } if(cnt == n-1) printf("%d\n", result); else printf("no\n"); } return 0; }