题意:
多组输入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的用法,待会我会另外写一篇博客,以供大家学习。
原文地址:https://www.cnblogs.com/YHH520/p/12253112.html
时间: 2024-11-06 09:31:01