hdu1879 最小生成树模板 peim和kruskal
来源:互联网 发布:菲律宾网络诈骗 编辑:程序博客网 时间:2024/06/11 04:04
Problem Description省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可)。现得到城镇道路统计表,表中列出了任意两城镇间修建道路的费用,以及该道路是否已经修通的状态。现请你编写程序,计算出全省畅通需要的最低成本。
Input测试输入包含若干测试用例。每个测试用例的第1行给出村庄数目N ( 1< N < 100 );随后的 N(N-1)/2 行对应村庄间道路的成本及修建状态,每行给4个正整数,分别是两个村庄的编号(从1编号到N),此两村庄间道路的成本,以及修建状态:1表示已建,0表示未建。
当N为0时输入结束。
Output每个测试用例的输出占一行,输出全省畅通需要的最低成本。
当N为0时输入结束。
思路,典型的最小生成数。鉴于网上有一些贴出来的模板可能有一些错误什么的,所以在这里我就贴出实现最小生成树的两种算法,peim和kruskal。
#include <stdio.h>#include <string.h>const int N=105;const int inf=10000000;int map[N][N],n;int vis[N*(N+1)/2];int dis[N*(N+1)/2];void Prime(){ memset(vis,0,sizeof(vis)); for(int i = 1 ; i <= n ; i++) { if(i==1)map[1][i]=inf; else dis[i]=map[1][i]; } int loc,sum=0; for(int i = 1 ; i <= n ; i++) { int min=inf; for(int j = 1 ; j <= n ; j++) { if(!vis[j]&&dis[j]<min) { min=dis[j]; loc=j; } } vis[loc]=1; sum+=min; for(int j = 1 ; j <= n ; j++) { if(!vis[j]&&map[loc][j]<dis[j]) { dis[j]=map[loc][j]; } } } printf("%d\n",sum);}int main(){ while(scanf("%d",&n),n) { for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { map[i][j]=inf; } } int m = n*(n-1)/2; int a,b,c,d; for(int i = 1 ; i <= m ; i++) { scanf("%d%d%d%d",&a,&b,&c,&d); if(d==1)map[a][b]=map[b][a]=0; else map[a][b]=map[b][a]=c; } Prime(); } return 0;}
/*典型的最小生成树,在做并查集时做的这道题,所以使用并查集实现的克鲁斯卡尔算法*/#include <iostream>#include <stdio.h>#include <algorithm>using namespace std;struct node { int start ,end,expense,flag;}data[5005];int father[105];void make_set(int n){ for(int i=1;i<=n;i++) father[i]=i;}int find_set(int x){ if(x^father[x]) father[x]=find_set(father[x]); return father[x];}int union_set(int x,int y){ x=find_set(x); y=find_set(y); if(x==y) return 0; father[x]=y; return 1;}bool cmp(node a,node b){ return a.expense<b.expense;}int main(){ int n; while(scanf("%d",&n)!=EOF) { if(!n) break; make_set(n); int ans=0; int m=(n-1)*n/2; for(int i=0;i<m;i++) { scanf("%d%d%d%d",&data[i].start,&data[i].end,&data[i].expense,&data[i].flag); if(data[i].flag)//当道路修通时,规定一节点为另一节点的父亲 father[data[i].start]=data[i].end; } sort(data,data+m,cmp);//按道路的花费升序排列 //在不构成环的前提下,选择最短的边,有贪心的思想 for(int i=0;i<m;i++) { if(union_set(data[i].start,data[i].end)) ans+=data[i].expense; } printf("%d\n",ans); } return 0;}
#include <stdio.h>#include <string.h>const int N=105;const int inf=10000000;int map[N][N],n;int vis[N*(N+1)/2];int dis[N*(N+1)/2];void Prime(){ memset(vis,0,sizeof(vis)); for(int i = 2 ; i <= n ; i++) { dis[i]=map[1][i]; } int loc,sum=0; for(int i = 2 ; i <= n ; i++) { int min=0; for(int j = 1 ; j <= n ; j++) { if(!vis[j]&&dis[j]>min) { min=dis[j]; loc=j; } } vis[loc]=1; sum+=min; for(int j = 2 ; j <= n ; j++) { if(!vis[j]&&map[loc][j]>dis[j]) { dis[j]=map[loc][j]; } } } printf("%d\n",sum);}int main(){ while(scanf("%d",&n)!=EOF) { for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { scanf("%d",&map[i][j]); } } Prime(); } return 0;}
0 0
- hdu1879 最小生成树模板 peim和kruskal
- hdu1879(kruskal求最小生成树)
- hdu1879及最小生成树模板
- hdu1879(Kruskal最小生成树)--继续畅通工程
- hdu1879 继续畅通工程 (kruskal求最小生成树)
- HDU1879 继续畅通工程 【图论】【最小生成树】【Kruskal】
- 最小生成树模板(Kruskal和prim)
- 最小生成树-kruskal模板
- 最小生成树kruskal模板
- 【模板】最小生成树Kruskal
- 【模板】Kruskal 最小生成树
- 【模板】Kruskal 最小生成树
- 最小生成树-kruskal 模板
- Kruskal模板 最小生成树
- hdu1879(最小生成树)
- hdu1879(最小生成树)
- HDU1879 并查集和最小生成树
- POJ1258-最小生成树-kruskal模板
- 用AFN时报错
- js判断复选框的数量
- OA系统的左侧菜单栏的菜单项的处理
- mac上mysql root密码忘记或权限错误的解决办法
- Android学习路线指南
- hdu1879 最小生成树模板 peim和kruskal
- Volley缓存-原理介绍
- Javascript:谈谈JS的全局变量跟局部变量
- Project Euler Problem 4
- 设计原则之迪米特法则
- Correspondence analysis application
- iOS 学习(深拷贝 浅拷贝)
- 搜索字符串strstr()函数
- Fresco通过后处理器(Postprocessor)生成仿skype字母和背景色的头像