首页 > 代码库 > 课程设计 问题 R: 自来水管道
课程设计 问题 R: 自来水管道
题目描述
你领到了一个铺设校园内自来水管道的任务。校园内有若干需要供水的点,每两个供水点可能存在多种铺设路径。对于每一种铺设路径,其成本是预知的。
任务要求最终铺设的管道保证任意两点可以直接或间接的联通,同时总成本最低。
输入
每个测试用例由多行组成,第一行是两个整数P和R,P代表供水点数(1<=P<=50),每个点都对应1到P中的一个唯一编号。R代表可能的铺设路径数,路径数可能有非常多。接下有R行,每行格式如下:
节点A编号 节点B编号 路径成本
路径成本不超过100。
测试用例之间有一空行分开。输入结束用P=0表示,注意没有R值。
输出
每个测试用例占用一行输出最低总成本。
样例输入
1 0 2 3 1 2 37 2 1 17 1 2 68 3 7 1 2 19 2 3 11 3 1 7 1 3 5 2 3 89 3 1 91 1 2 32 5 7 1 2 5 2 3 7 2 4 8 4 5 11 3 5 10 1 5 6 4 2 12 0
样例输出
0 17 16 26
题意:P个点,给出两个点间的间的距离,求最小生成树所需的成本。
思路:克鲁斯卡尔算法。将给出的边按权值进行排序,遍历所有的边,如果该边的两个顶点不连通,则加入到生成树中。
用sort函数排序权值。关键在于判断该两点是否连通。我用了并查集的思想。若两点联通则将一点的终节点指向另一点的终节点(用了数组b来存,b[i]就表示节点i指向的下一个节点)。
先初始化,让b[i]=i。用自定义函数f(i)求i节点的终节点。如果两节点a,b的f(a)和f(b)不想等。说明a,b,两节点不连通。
#include<cstdio> #include<algorithm> using namespace std; typedef struct { int v[3]; } p; //用来存两个供水点和之间的距离 bool comp(p a, p b) //按v[2]中的元素进行比较 { return a.v[2] < b.v[2]; } p a[10000005]; int b[105]; int f(int i) //寻找终节点 { if(b[i]==i) return i;
else return f(b[i]); //应该可以优化成 return b[i]=f(b[i]); } int main() { int i,t,n,s,j; while(scanf("%d",&n)==1&&n) { s=0; scanf("%d",&t); for(i=1; i<=t; i++) scanf("%d%d%d",&a[i].v[0],&a[i].v[1],&a[i].v[2]); sort(a,a+t,comp); for(i=1; i<=n; i++) b[i]=i; for(i=1; i<=t; i++) { if(f(a[i].v[0])!=f(a[i].v[1])) //如果不连通就加入生成树中并累加路径 { s+=a[i].v[2]; b[f(a[i].v[0])]=f(a[i].v[1]); //将一点的终节点指向另一点的终节点 } } printf("%d\n",s); } return 0; }
课程设计 问题 R: 自来水管道
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。