数据结构实验之图论六:村村通公路
Time Limit: 1000MS
Memory Limit: 65536KB
Problem Description
当前农村公路建设正如火如荼的展开,某乡镇政府决定实现村村通公路,工程师现有各个村落之间的原始道路统计数据表,表中列出了各村之间可以建设公路的若干条道路的成本,你的任务是根据给出的数据表,求使得每个村都有公路连通所需要的最低成本。
Input
连续多组数据输入,每组数据包括村落数目N(N <= 1000)和可供选择的道路数目M(M <= 3000),随后M行对应M条道路,每行给出3个正整数,分别是该条道路直接连通的两个村庄的编号和修建该道路的预算成本,村庄从1~N编号。
Output
输出使每个村庄都有公路连通所需要的最低成本,如果输入数据不能使所有村庄畅通,则输出-1,表示有些村庄之间没有路连通。
Example Input
5 8 1 2 12 1 3 9 1 4 11 1 5 3 2 3 6 2 4 9 3 4 4 4 5 6
Example Output
19
Hint
Author
xam
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f #define N 1100 using namespace std; int mp[N][N]; //邻接矩阵存储图 int dis[N]; //标记数组 int vis[N]; //用来记录当前生成树到每个节点的距离 int sum, n, m;//n代表节点数 sum保存生成树的权值总和 void prim() { sum=0; //最小生成树的权值总和初始化为0 int mm; memset(vis, false, sizeof(vis)); //初始化节点均没有被访问 for(int i = 1; i <= n; i++) { dis[i] = mp[1][i]; //我们从0号节点开始生成树 } vis[1] = true; //生成树的根(起点)标记访问 int pos; //用来记录每一次循环找到的节点的编号 int d = 0; //标记变量 for(int i = 1; i < n; i++) //要生成n-1条边,所以循环n-1次 { mm = INF; for(int j = 1; j <= n; j++) //对dis数组进行遍历,找到值最小的 { if(!vis[j] && dis[j] < mm) { mm = dis[j]; pos = j; } } if(mm == INF) //如果在此跳出循环,表示有城市之间不能连通 { d = 1; break; } sum += mm; //加上找到的最小权值 vis[pos] = true; //标记找到的该节点被访问 for(int j = 1; j <= n; j++) //更新dis数组 { if(!vis[j] && dis[j] > mp[pos][j]) { dis[j] = mp[pos][j]; //如果该点还没有被访问过, //更新生成树到该点的距离; } } } if(d == 0) printf("%d\n", sum); //n-1次循环完毕后输出权值总和 else printf("-1\n"); } int main() { while(cin >> n >> m) { for(int i = 1; i <= n; i++) { for(int j = 1; j <= n; j++) //对mp数组初始化 { if(i == j) mp[i][j] = 0; else mp[i][j] = INF; } } while(m--) { int a, b, c; scanf("%d%d%d", &a, &b, &c); if(mp[a][b] > c) //如果存在重边,取最小值 mp[a][b] = mp[b][a] = c; } prim(); //执行普利姆算法 } return 0; }