畅通工程(并查集模版题)

题意:

多组输入N,M,当N为0退出人输入,N是道路数目,M是村庄总数,随后N行,每行输入三个数两个村庄的编号,以及连接这两个村庄的费用。
对每一组数据输出畅通工程的最低费用,如果不能畅通就输出“?”(不包括双引号)

这道题有两道链接:

一道是fjut的链接,另外一道是hdu的

http://www.fjutacm.com/Problem.jsp?pid=1214

http://acm.hdu.edu.cn/showproblem.php?pid=1863

思路:其实这道题就是一道排序+并查集题,将每条路的费用进行排序然后依次合并,然后费用增加,当N中情况都试过了,再来一个循环判断是否全部连接。

好啦,我们来看AC代码吧:

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<string.h>
using namespace std;
int fa[105];
struct node//定义这个结构体,a代表的是一个村庄的编号,b代表的是另一个村庄的编号,cost顾名思义 
{
    int a;
    int b;
    int cost;    
};
int find(int x)
{
    int r=x,temp;
    while(r!=fa[r])
    r=fa[r];
    while(x!=fa[x])
    {
        temp=fa[x];
        fa[x]=r;
        x=temp;
    }
    return x;
}
bool cmp(node x,node y)//cmp排序 
{
    return x.cost<y.cost;
}
int main(void)
{
    int n,m;
    node cp[500];
    while(cin>>n>>m&&n)
    {
        int sum=0;
        for(int i=1;i<=m;i++)
        fa[i]=i;
        for(int i=1;i<=n;i++)
        {
            cin>>cp[i].a>>cp[i].b>>cp[i].cost;
        }
        sort(cp+1,cp+n+1,cmp);//排序 
        for(int i=1;i<=n;i++)//这个循环开始处理费用 
        {
            int x=find(cp[i].a);
            int y=find(cp[i].b);
            if(x!=y)
            {
                fa[y]=x;
                sum+=cp[i].cost;
            }
        }
        int k=find(1);
        int flag=1;
        for(int i=1;i<=m;i++)//这个循环检查是否村子都连接 
        {
            if(k!=find(i))
            {
                flag=0;
                break;
            }
    }
    if(flag)
    cout<<sum<<endl;
    else
    cout<<'?'<<endl;
}
return 0;
}

小结一下:这道题也算一道模版题吧,只不过可能开始有点难想,为什么要对费用排序,骑士想通了就觉得很简单,sort的自定义排序我也学了一波还是挺好用的,cmp的用法,待会我会另外写一篇博客,以供大家学习。

posted @ 2020-02-02 18:23  MangataTS  阅读(359)  评论(0编辑  收藏  举报