poj 2421 (最小生成树 Prime+kruskal)
来源:互联网 发布:弗莱贝格工业大学 知乎 编辑:程序博客网 时间:2024/05/13 12:21
Constructing Roads
Time Limit: 2000MS Memory Limit: 65536KTotal Submissions: 22145 Accepted: 9440
Description
There are N villages, which are numbered from 1 to N, and you should build some roads such that every two villages can connect to each other. We say two village A and B are connected, if and only if there is a road between A and B, or there exists a village C such that there is a road between A and C, and C and B are connected.
We know that there are already some roads between some villages and your job is the build some roads such that all the villages are connect and the length of all the roads built is minimum.
We know that there are already some roads between some villages and your job is the build some roads such that all the villages are connect and the length of all the roads built is minimum.
Input
The first line is an integer N (3 <= N <= 100), which is the number of villages. Then come N lines, the i-th of which contains N integers, and the j-th of these N integers is the distance (the distance should be an integer within [1, 1000]) between village i and village j.
Then there is an integer Q (0 <= Q <= N * (N + 1) / 2). Then come Q lines, each line contains two integers a and b (1 <= a < b <= N), which means the road between village a and village b has been built.
Then there is an integer Q (0 <= Q <= N * (N + 1) / 2). Then come Q lines, each line contains two integers a and b (1 <= a < b <= N), which means the road between village a and village b has been built.
Output
You should output a line contains an integer, which is the length of all the roads to be built such that all the villages are connected, and this value is minimum.
Sample Input
30 990 692990 0 179692 179 011 2
Sample Output
179
Source
点击打开题目链接http://poj.org/problem?id=2421
题意:给出n,n个村庄,然后给你n*n的矩阵,表示i村庄到j村庄的距离,下面给的是Q对数据,表示啊a,b之间已经建好了路,不必再建。
分析: 把已经建过的路看作0,用Prime即可求出,Kruskal则把已经建好路的村庄归为用一集合;
Prime:
#include <iostream>#include <cstdio>#include <cstring>#include <queue>#include <algorithm>#include <math.h>typedef long long ll;using namespace std;#define INF 0x3f3f3f3f#define N 110int maps[N][N],vis[N],dis[N];int n,m,q;void init(int n){ int i,j; for(i=0;i<=n;i++) for(j=0;j<=n;j++) maps[i][j]=(i==j)?0:INF;}int Prime(int s){ int i,j,index,Min,sum=0; for(i=1;i<=n;i++) { dis[i]=maps[1][i]; vis[i]=0; } vis[s]=1; for(i=1;i<=n;i++) { Min=INF,index=-1; for(j=1;j<=n;j++) { if(!vis[j] && Min>dis[j]) { Min=dis[j]; index=j; } } if(index==-1) break; sum=sum+Min; vis[index]=1; for(j=1;j<=n;j++) { if(!vis[j] && dis[j]>maps[index][j]) dis[j]=maps[index][j]; } } return sum;}int main(){ int i,j,x,a,b; while(scanf("%d",&n)!=EOF) ///这里记住以EOF结束,以n!=0,则TLE; { init(n); for(i=1;i<=n;i++) { for(j=1;j<=n;j++) { scanf("%d",&x); maps[i][j]=maps[j][i]=x; } } scanf("%d",&q); while(q--) { scanf("%d%d",&a,&b); maps[a][b]=maps[b][a]=0; ///把已经建好的路赋值为0; } int ans=Prime(1); printf("%d\n",ans); } return 0;}
#include <iostream>#include <stdio.h>#include <string.h>#include <queue>#include <algorithm>#include <stdlib.h>#include <math.h>typedef long long ll;using namespace std;#define INF 0x3f3f3f3f#define N 11000int father[N];int maps[110][110];struct node{ int s,e,w;}p[N];int cmp(node a,node b) ///排序,按照路径的由短到长排序{ return a.w<b.w;}int Find(int x) ///查找父节点...{ while(x!=father[x]) x=father[x]; return x;}int main(){ int n,m,i,j,ans,a,b,x; while(scanf("%d",&n)!=EOF) { for(i=1;i<=n;i++) ///初始化。父节点为其本身 father[i]=i; for(i=1;i<=n;i++) { for(j=1;j<=n;j++) { scanf("%d",&x); maps[i][j]=x; } } int num=0; for(i=2;i<=n;i++) ///注意循环条件 ,目的是把他们存入结构体P中。 { for(j=1;j<i;j++) { p[num].s=i; p[num].e=j; p[num].w=maps[i][j]; num++; } } scanf("%d",&m); while(m--) { scanf("%d%d",&a,&b); int x,y; x=Find(a); y=Find(b); if(x!=y) father[y]=x; ///已经建好路的,归为同一集合 } sort(p,p+num,cmp); ///路径按从小到大 排序 ans=0; for(i=0;i<num;i++) { int x,y; x=Find(p[i].s); y=Find(p[i].e); if(x==y) continue; else { ans=ans+p[i].w; father[x]=y; } } printf("%d\n",ans); } return 0;}
看了人家的代码才知道自己有多水,注意代码风格的培养,简洁的代码,才是大牛的作风....
下面的附录是一位大牛的代码:(借鉴借鉴 毕竟太菜......)
#include<iostream>using namespace std;int a[101][101],n,father[101],m,x,y;int get_father(int p){ return father[p]=(father[p]==p? p:get_father(father[p]));}int main(){ cin>>n; for(int i=0;i<n;i++) for(int j=0;j<n;j++) cin>>a[i][j]; for(int i=0;i<n;i++)father[i]=i; cin>>m; for(int i=0;i<m;i++){ cin>>x>>y; father[get_father(x-1)]=get_father(y-1); } int sum=0; for(int k=1;k<=1000;k++) for(int i=0;i<n;i++) for(int j=0;j<n;j++) if(a[i][j]==k&&get_father(i)!=get_father(j)){ sum+=a[i][j]; father[father[i]]=father[j]; } cout<<sum<<endl; return 0;}
0 0
- poj 2421 (最小生成树 Prime+kruskal)
- poj 1287 (最小生成树 Prime + kruskal )
- poj 2349(Prime + Kruskal 最小生成树)
- poj 1751 (最小生成树 Prime+kruskal 路径输出)
- poj2485-最小生成树(prime+kruskal)
- 最小生成树---Kruskal/Prime算法
- 最小生成树(Prime/kruskal)
- 最小生成树算法[Prime/(Kruskal)]
- 【图论】【最小生成树】【kruskal+prime】
- 最小生成树(Prime and Kruskal)
- HDU 1301 &POJ 1215 Jungle Roads【最小生成树,Prime算法+Kruskal算法】
- Agri-Net(POJ 1258)(裸最小生成树)(Prime算法+Kruskal算法)
- 最小生成树的prime和kruskal算法
- 最小生成树(kruskal算法)和 (Prime算法)
- 图论-最小生成树-prime算法&Kruskal算法 c++
- EOJ2067 最小生成树 prime算法+kruskal算法
- hdu1863 畅通工程 Kruskal 和 Prime求最小生成树
- poj-2421 Constructing Roads(最小生成树 Kruskal算法)
- 第18章-Java IO系统
- 施一公教授演讲(转载自:互助吧网站)
- Maven实战(一)--Why Maven
- JavaSE基础(一)
- switch 中一旦 case 匹配,就会顺序执行后面的程序代码
- poj 2421 (最小生成树 Prime+kruskal)
- 算法的时间复杂度(理论篇)
- 字符串变换
- Jump Game
- boost开发指南
- 烧写程序(下载程序)基础知识
- 训练第二周之DFS(深度优先搜索)
- UVA-10785 The Mad Numerologist
- 堆排序