首页 > 其他 > 详细

hdu1233还是畅通工程 最小生成树(prim或kruskal)

时间:2015-08-17 17:20:40      阅读:195      评论:0      收藏:0      [点我收藏+]

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

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!