hdu 1102 Constructing Roads (prim 、kruskal)
2014-03-09 21:23
495 查看
Constructing Roads
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 12235 Accepted Submission(s): 4655
Problem 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.
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.
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
3 0 990 692 990 0 179 692 179 0 1 1 2
Sample Output
179
prim算法求最小生成树,把已经建好的边值置为0
#include"stdio.h" #include"string.h" #include"math.h" #define N 105 const int Inf=10000; int main() { int n,q,i,j,a,b,ans,s,index,min; int map ,mark ,dis ; while(scanf("%d",&n)!=-1) { for(i=1;i<=n;i++) for(j=1;j<=n;j++) scanf("%d",&map[i][j]); scanf("%d",&q); while(q--) //已经连通的的点距离改记为0; { scanf("%d%d",&a,&b); map[a][b]=0; map[b][a]=0; } s=1; //先加入一个点,然后更新其余点与该点的距离 ans=0; memset(mark,0,sizeof(mark)); mark[1]=1; for(i=1;i<=n;i++) dis[i]=map[s][i]; while(1) { index=1; min=Inf; for(i=1;i<=n;i++) if(!mark[i]&&dis[i]<min) //找到距离该点最近的点,加入集合 { index=i; min=dis[i]; } if(index==1) //完成建路任务 break; mark[index]=1; ans+=min; for(i=1;i<=n;i++) //若存在集合外的点距离新加入点的距离小于以前距离,更新 if(!mark[i]&&map[index][i]<dis[i]) dis[i]=map[index][i]; } printf("%d\n",ans); } return 0; }
kruskal算法:
#include"stdio.h" #include"string.h" #include"iostream" #include"queue" #include"algorithm" using namespace std; #define N 105 #define inf 0x7fffffff int pre ,cnt; struct node { int u,v,d; }e[N*N]; bool cmp(node a,node b) { return a.d<b.d; } int find(int x) { if(x!=pre[x]) pre[x]=find(pre[x]); return pre[x]; } void kruskal(int n,int k) { int i,sum=0,f1,f2; for(i=0;i<k;i++) { f1=find(e[i].u); f2=find(e[i].v); if(f1!=f2) { pre[f1]=f2; sum+=e[i].d; if(cnt>=n-1) break; } } printf("%d\n",sum); } int main() { int n,i,j,k,m,d,u,v; while(scanf("%d",&n)!=-1) { for(k=i=0;i<n;i++) { for(j=0;j<n;j++) { scanf("%d",&d); if(j>=i) continue; e[k].u=i; e[k].v=j; e[k++].d=d; } } for(i=0;i<n;i++) pre[i]=i; scanf("%d",&m); cnt=0; while(m--) { scanf("%d%d",&u,&v); int f1,f2; f1=find(u-1); f2=find(v-1); if(f1!=f2) { pre[f1]=f2; cnt++; } } sort(e,e+k,cmp); kruskal(n,k); } return 0; }
相关文章推荐
- hdu1102 - Constructing Roads (求最小生成树) (Prim & Kruskal)
- HDU1102 Constructing Roads 最小生成树prim||kruskal
- HDU 1102:Constructing Roads【Kruskal & Prim】
- hdu 1102 Constructing Roads(kruskal || prim)
- hdu 1102 Constructing Roads(kruskal || prim)
- HDU-#1102 Constructing Roads(Prim & Kruskal)
- hdu_1875_畅通工程再续 prim和kruskal
- HDU 1102 Constructing Roads, Prim+优先队列
- hdu 1102 Constructing Roads(最小生成树,prim)
- HDU - 1102 Constructing Roads(最小生成树kruskal)
- hdu 1162 Eddy's picture 最小生成树入门题 Prim+Kruskal两种算法AC
- hdu 1102 prim简单
- hdu1102之prim(堆优化)解法
- hdu 1102 最小生成树 prim
- HDU 1233 又是畅通工程 [kruskal]+[prim]【最小生成树入门】
- HDU 1879 继续畅通工程 (Prim(普里姆算法)+Kruskal(克鲁斯卡尔))
- 【最小生成树 kruskal】 hdu 1102 Constructing Roads
- HDU 1102 Constructing Roads(prim求最小生成树)
- HDU-1102(prim求最小生成树)
- 图论 最短路 HDU 1875 畅通工程再续(prim)(Kruskal)