Problem Description
某省调查乡村交通状况,得到的统计表中列出了任意两村庄间的距离。省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可),并要求铺设的公路总长度为最小。请计算最小的公路总长度。
Input
测试输入包含若干测试用例。每个测试用例的第1行给出村庄数目N ( < 100 );随后的N(N-1)/2行对应村庄间的距离,每行给出一对正整数,分别是两个村庄的编号,以及此两村庄间的距离。为简单起见,村庄从1到N编号。
当N为0时,输入结束,该用例不被处理。
Output
对每个测试用例,在1行里输出最小的公路总长度。
Sample Input
3
1 2 1
1 3 2
2 3 4
4
1 2 1
1 3 4
1 4 1
2 3 3
2 4 2
3 4 5
0
Sample Output
3
5
Hint
Hint
Huge input, scanf is recommended.
Source
浙大计算机研究生复试上机考试-2006年
这里给出两种解法(求最小生成树的常用两种解法):
(1)prim算法·
#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<vector>
#include<map>
#include<stack>
#pragma comment(linker,"/STACK:102400000,102400000")
#define pi acos(-1.0)
#define EPS 1e-6
#define INF (1<<24)
using namespace std;
int cost[105][105];
int mincost[105];
bool used[105];
int V;
int prim() //
{
int i;
for(i=0;i<=V;i++)
{
mincost[i]=INF;
used[i]=false;
}
mincost[1]=0;
int res=0;
while(true)
{
int v=-1;
for(int u=1;u<=V;u++)
{
if(!used[u]&&(v==-1||mincost[u]<mincost[v])) v=u;
}
if(v==-1) break;
used[v]=true;
res=res+mincost[v];
for(int u=1;u<=V;u++)
{
mincost[u]=min(mincost[u],cost[v][u]);
}
}
return res;
}
int main()
{
while(scanf("%d",&V),V!=0)
{
int i,j;
int x,y,b;
for(i=1;i<=V;i++)
{
cost[i][i]=0;
for(j=1;j<=V;j++)
cost[i][j]=INF;
}
for(i=0;i<V*(V-1)/2;i++)
{
scanf("%d %d %d",&x,&y,&b);
cost[x][y]=b;
cost[y][x]=b;
}
printf("%d\n",prim());
}
return 0;
}
(2)kruskal算法:(会用到并查集)
按圈从小到大排序。。从小到大去出,两点父节点不一样,这加入树中,。,,
#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<vector>
#include<map>
#include<stack>
#pragma comment(linker,"/STACK:102400000,102400000")
#define pi acos(-1.0)
#define EPS 1e-6
#define INF (1<<24)
using namespace std;
struct EDGE{
int x,y,value;
}edge[10005];
int father[105];
int p;
int n;
bool cmp(struct EDGE a,struct EDGE b)
{
return a.value<b.value;
}
int findfather(int x)
{
if(x!=father[x])
father[x]=findfather(father[x]);
return father[x];
}
void Uion(int x,int y)
{
int a=findfather(x);
int b=findfather(y);
father[a]=b;
}
bool same(int x,int y)
{
if(findfather(x)==findfather(y)) return true;
else return false;
}
int kruskal()
{
int i;
for(i=0;i<=n;i++) father[i]=i;
int res=0;
for(i=0;i<p;i++)
{
if(same(edge[i].x,edge[i].y)==false)
{
Uion(edge[i].x,edge[i].y);
res+=edge[i].value;
}
}
return res;
}
int main()
{
while(scanf("%d",&n),n!=0)
{
int i;
p=n*(n-1)/2;
for(i=0;i<p;i++)
{
scanf("%d %d %d",&edge[i].x,&edge[i].y,&edge[i].value);
}
sort(edge,edge+p,cmp);
printf("%d\n",kruskal());
}
return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
hdu1233还是畅通工程 最小生成树(prim或kruskal)
原文:http://blog.csdn.net/xtulollipop/article/details/47727093