HDU 1863 畅通工程(Prim,Kruskal,邻接表模板)

Posted 蔡军帅

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU 1863 畅通工程(Prim,Kruskal,邻接表模板)相关的知识,希望对你有一定的参考价值。

畅通工程

Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 35957    Accepted Submission(s): 15971


Problem Description
省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可)。经过调查评估,得到的统计表中列出了有可能建设公路的若干条道路的成本。现请你编写程序,计算出全省畅通需要的最低成本。
 

 

Input
测试输入包含若干测试用例。每个测试用例的第1行给出评估的道路条数 N、村庄数目M ( < 100 );随后的 N 
行对应村庄间道路的成本,每行给出一对正整数,分别是两个村庄的编号,以及此两村庄间道路的成本(也是正整数)。为简单起见,村庄从1到M编号。当N为0时,全部输入结束,相应的结果不要输出。
 

 

Output
对每个测试用例,在1行里输出全省畅通需要的最低成本。若统计数据不足以保证畅通,则输出“?”。
 

 

Sample Input
3 3 1 2 1 1 3 2 2 3 4 1 3 2 3 2 0 100
 

 

Sample Output
3 ?
 

 

Source
 

 

Recommend
lcy   |   We have carefully selected several similar problems for you:  1879 1233 1875 1232 1102 
 
Pim
#include<iostream>
#include<cstring>
#include<algorithm>
#include<string>
#include<cmath>
#define inf 0x3f3f3f3f
using namespace std;
int d[100005];
struct node
{
    int v;
    int c;
    int nxt;
}e[100005];
int head[100005];
int cnt=1;
bool book[10005];
void add(int u,int v,int c)
{
    e[cnt].c=c;
    e[cnt].v=v;
    e[cnt].nxt=head[u];
    head[u]=cnt++;
}
int main()
{
    int n,m;
    while(cin>>m>>n)
    {
        if(m==0) break;
        cnt=1;
        memset(d,inf,sizeof(d));
        memset(head,-1,sizeof(head));
        memset(book,0,sizeof(book));
        for(int i=1;i<=m;i++)
        {
            int x,y,z;
            cin>>x>>y>>z;
            add(x,y,z);
            add(y,x,z);
        }
        for(int i=head[1];i!=-1;i=e[i].nxt)
        {
            if(d[e[i].v]>e[i].c)
            {
                d[e[i].v]=e[i].c;
            }
        }
        d[1]=0;
        book[1]=1;
        bool f=1;
        int sum=0;
        for(int i=1;i<=n-1;i++)
        {
            int k=-1;
            int min=inf;
            for(int j=1;j<=n;j++)
            {
                if(!book[j]&&min>d[j])
                {
                    min=d[j];
                    k=j;
                }
            }
            if(k==-1)
            {
                f=0;
                break;
            }
            book[k]=1;
            sum+=d[k];
            for(int j=head[k];j!=-1;j=e[j].nxt )
            {
                int x=e[j].v;
                int c=e[j].c;
                if(!book[x]&&d[x]>c)
                {
                    d[x]=c;
                }
            }
        }
        if(!f) cout<<"?"<<endl;
        else cout<<sum<<endl;
    }
    return 0;
}

kruskal

#include<iostream>
#include<cstring>
#include<algorithm>
#include<string>
#include<cmath>
#define inf 0x3f3f3f3f
using namespace std;
int pra[100005];
struct node
{
    int u,v,c;
}e[100005];
bool cmp(node x,node y)
{
    return x.c<y.c;
}
int find(int x)
{
    if(pra[x]==x) return x;
    else return pra[x]=find(pra[x]);
}
void unite(int x,int y)
{
    x=find(x);
    y=find(y);
    if(x==y) return;
    else 
    {
        pra[x]=y;
    }
}
int main()
{
    int n,m;
    while(cin>>m>>n)
    {
        if(m==0) break;
        for(int i=1;i<=n;i++) pra[i]=i;
        for(int i=1;i<=m;i++)
        {
            cin>>e[i].u>>e[i].v>>e[i].c;
        }
        sort(e+1,e+m+1,cmp);
        int sum=0;
        int k=0;
        for(int i=1;i<=m;i++)
        {
            int x=e[i].u;x=find(x);
            int y=e[i].v;y=find(y);
            if(x!=y)
            {
                unite(x,y);
                k++;
                sum+=e[i].c;
            }
            if(k==n-1) break;
        }
        if(k==n-1) cout<<sum<<endl;
        else cout<<"?"<<endl;
    }
    return 0;
}

 

 

以上是关于HDU 1863 畅通工程(Prim,Kruskal,邻接表模板)的主要内容,如果未能解决你的问题,请参考以下文章

HDU 1863 畅通工程

Hdu 1863 畅通工程

HDU 1863 畅通工程

HDU 1863 畅通工程

hdu 1863 畅通工程 (并查集 kruskal)

HDU1863 畅通工程---(最小生成树)