数据结构实验之图论六:村村通公路
2019-08-06 22:52
387 查看
数据结构实验之图论六:村村通公路
Time Limit: 1000 ms Memory Limit: 65536 KiB
Problem Description
当前农村公路建设正如火如荼的展开,某乡镇政府决定实现村村通公路,工程师现有各个村落之间的原始道路统计数据表,表中列出了各村之间可以建设公路的若干条道路的成本,你的任务是根据给出的数据表,求使得每个村都有公路连通所需要的最低成本。
Input
连续多组数据输入,每组数据包括村落数目N(N <= 1000)和可供选择的道路数目M(M <= 3000),随后M行对应M条道路,每行给出3个正整数,分别是该条道路直接连通的两个村庄的编号和修建该道路的预算成本,村庄从1~N编号。
Output
输出使每个村庄都有公路连通所需要的最低成本,如果输入数据不能使所有村庄畅通,则输出-1,表示有些村庄之间没有路连通。
Sample 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
Sample Output
19
#include<bits/stdc++.h> #define INF 0x3f3f3f3f using namespace std; int mmap[1111][1111];///邻接矩阵存储图 int vis[1111]; ///标记数组 int dis[1111]; /// int prim(int n) { for(int i = 2; i <= n; i++) dis[i] = mmap[1][i]; ///我们从0号节点开始生成树 vis[1] = 1; ///生成树的根(起点)标记访问 int now; ///用来记录每一次循环找到的节点的编号 int sum = 0; ///最小生成树的权值总和初始化为0 int mmin; for(int i = 2; i <= n; i++)///要生成n-1条边,所以循环n-1次 { mmin = INF; for(int j = 2; j <= n; j++)///对dis数组进行遍历,找到值最小的 { if(!vis[j] && dis[j] < mmin) { mmin = dis[j]; now = j; } } sum += mmin; ///加上找到的最小权值 vis[now] = 1; ///标记找到的该节点被访问 if(mmin == INF) ///如果在此跳出循环,表示有城市之间不能连通 return -1;///这个地方要注意,if()语句必须放在下面的循环前面,因为下面的是更新下一步的距离,为下一次循环准备 for(int j = 2; j <= n; j++) { if(!vis[j] && dis[j] > mmap[now][j]) dis[j] = mmap[now][j];///如果该点还没有被访问过, } ///更新生成树到该点的距离; } return sum; } int main() { int n, m; while(cin>>n>>m) { int a, b, c; memset(vis, 0, sizeof(vis));///初始化节点均没有被访问 memset(dis, 0, sizeof(dis)); for(int i = 1; i <= n; i++) { for(int j = 1; j <= n; j++) { if(i == j) mmap[i][j] = 0; else mmap[i][j] = INF; } } while(m--) { scanf("%d%d%d", &a, &b, &c); if(mmap[a][b] > c)///如果存在重边,取最小值 mmap[a][b] = mmap[b][a] = c; } cout<<prim(n)<<endl;///n指的是点的个数,不是起点数 } return 0; }
prim算法思路:
任一个顶点 u 作为生成树的根,
之 后往生成树上添加新的顶点 v在添加的顶点 w 和已经在生成树上的顶点v 之间必定存在一条边,
并且该边的权值在所有连通顶点 u和 v 之间的边中取值最小
之后继续往生成树上添加顶点,直至生成树上含有 n-1 个顶点为止。
上面是自己看着写的,下面是大神的,介绍prim算法,下面是它的代码
https://www.geek-share.com/detail/2619186140.html
#include<iostream> #include<fstream> using namespace std; #define MAX 100 #define MAXCOST 0x7fffffff int graph[MAX][MAX]; int prim(int graph[][MAX], int n) { int lowcost[MAX]; int mst[MAX]; int i, j, min, minid, sum = 0; for (i = 2; i <= n; i++) { lowcost[i] = graph[1][i]; mst[i] = 1; } mst[1] = 0; for (i = 2; i <= n; i++) { min = MAXCOST; minid = 0; for (j = 2; j <= n; j++) { if (lowcost[j] < min && lowcost[j] != 0) { min = lowcost[j]; minid = j; } } cout << "V" << mst[minid] << "-V" << minid << "=" << min << endl; sum += min; lowcost[minid] = 0; for (j = 2; j <= n; j++) { if (graph[minid][j] < lowcost[j]) { lowcost[j] = graph[minid][j]; mst[j] = minid; } } } return sum; } int main() { int i, j, k, m, n; int x, y, cost; ifstream in("input.txt"); in >> m >> n;//m=顶点的个数,n=边的个数 //初始化图G for (i = 1; i <= m; i++) { for (j = 1; j <= m; j++) { graph[i][j] = MAXCOST; } } //构建图G for (k = 1; k <= n; k++) { in >> i >> j >> cost; graph[i][j] = cost; graph[j][i] = cost; } //求解最小生成树 cost = prim(graph, m); //输出最小权值和 cout << "最小权值和=" << cost << endl; system("pause"); return 0; }
相关文章推荐
- 数据结构实验之图论六:村村通公路
- [SDUT](3362)数据结构实验之图论六:村村通公路 ---最小生成树(图)
- 数据结构实验之图论六:村村通公路
- 数据结构实验之图论六:村村通公路
- 数据结构实验之图论六:村村通公路
- 数据结构实验之图论六:村村通公路
- 数据结构实验之图论六:村村通公路
- 数据结构实验之图论六:村村通公路
- 数据结构实验之排序四:寻找大富翁
- 数据结构实验之查找五:平方之哈希表
- 数据结构实验之二叉树五:层序遍历
- 数据结构实验1_顺序表的操作
- SDUT 3363-数据结构实验之图论七:驴友计划(最短路_dijkstra)
- 数据结构实验之查找三:树的种类统计
- SDUT-1804-数据结构实验之二叉树八:(中序后序)求二叉树的深度
- 3362 数据结构实验之图论六:村村通公路
- sdutoj 3362 数据结构实验之图论六:村村通公路(最小生成树(裸的))
- 数据结构实验之排序五:归并求逆序数
- 数据结构图的综合实验代码
- 数据结构实验之链表七:单链表中重复元素的删除