nyoj38(最小生成树)

来源:互联网 发布:websocket聊天室源码 编辑:程序博客网 时间:2024/05/16 14:42

布线问题

时间限制:1000 ms  |  内存限制:65535 KB
难度:4
描述
南阳理工学院要进行用电线路改造,现在校长要求设计师设计出一种布线方式,该布线方式需要满足以下条件:
1、把所有的楼都供上电。
2、所用电线花费最少
输入
第一行是一个整数n表示有n组测试数据。(n<5)
每组测试数据的第一行是两个整数v,e.
v表示学校里楼的总个数(v<=500)
随后的e行里,每行有三个整数a,b,c表示a与b之间如果建铺设线路花费为c(c<=100)。(哪两栋楼间如果没有指明花费,则表示这两栋楼直接连通需要费用太大或者不可能连通)
随后的1行里,有v个整数,其中第i个数表示从第i号楼接线到外界供电设施所需要的费用。( 0<e<v*(v-1)/2 )
(楼的编号从1开始),由于安全问题,只能选择一个楼连接到外界供电设备。
数据保证至少存在一种方案满足要求。
输出
每组测试数据输出一个正整数,表示铺设满足校长要求的线路的最小花费。
样例输入
14 61 2 102 3 103 1 101 4 12 4 13 4 11 3 5 6
样例输出
4

解题思路:其实很简单,这题就是考无向图的无环最小生成树,求最短的路径;

代码如下:我用的是Kruskal算法,用prim算法一样的也可以解决问题

#include<iostream>#include<stioh> #include<algorithm>using namespace std;#define M 250005 //最多边数#define N 505 //最多顶点数typedef struct edge{    int a;    int b;    int value;}edge;edge edges[M];int final[N],num1[N];            //存储父节点 int nodecount[N];        //存储该节点孩子结点的个数 bool cmp(edge a,edge b){     return a.value<b.value;}int findp(int n)            //寻找父节点 {    if(final[n]==n)        return n;    else        final[n]=findp(final[n]);    return final[n];}bool Union(int x,int y)          //合并 {    int rootx=findp(x);    int rooty=findp(y);    if(rootx==rooty)        return false;    else if(nodecount[rootx]<=nodecount[rooty])    {        final[rootx]=rooty;        nodecount[rooty]+=nodecount[rootx];    }    else    {        final[rooty]=rootx;        nodecount[rootx]+=nodecount[rooty];    }    return true;}int main (){    //freopen("1.txt","r",stdin);    int num=0;    int n,m,sum,k;    int i;cin>>k;    while (k-- )    {scanf ( "%d%d", &n, &m );        num=0;              //记录生成树中的边的数目     sum=0;        for(i=1;i<=m;i++)        {            scanf("%d%d%d",&edges[i].a,&edges[i].b,&edges[i].value);        }for(i=1;i<=n;i++)cin>>num1[i];        for(i=1;i<=n;i++)      //初始化                        {            final[i]=i;            nodecount[i]=1;        }        sort(edges+1,edges+m+1,cmp);   //排序                                     for(i=1;i<=m;i++)              //遍历所有的边         {            if(Union(edges[i].a,edges[i].b))         //合并             {                num++;//记录最小生成树的边数sum+=edges[i].value;//printf("%d->%d\n",edges[i].a,edges[i].b);            }            if(num==n-1)               //找到了最小生成树                 break;        }sort(num1+1,num1+n+1);printf("%d\n",sum+num1[1]);    }    return 0;}//kruskal算法模板




0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 黑魂3暗灵入侵怎么办 问道手游账号忘了怎么办 问道手游密码忘了怎么办 毒蚂蚁咬了红肿怎么办 电脑开机后有电流声怎么办 小学生阅读方面不会总结怎么办 天龙八部手游转职装备怎么办 投简历没回应该怎么办? 开车开的腰疼怎么办 开车腰疼怎么办吃什么 58简历投错了怎么办 开了一天车腰疼怎么办 开车腰疼怎么办怎么解决好 球球大作战找不到主界面怎么办 在QQ上找不到主界面怎么办 mac地址被过滤了怎么办 续贷声明含非法字符怎么办 辞职老板不给结工资怎么办 辞职后老板不发工资怎么办 联想手机不自带系统升级怎么办 苹果6玩崩坏3卡怎么办 机票名字打错了怎么办? 安装软件后显示名字乱码怎么办 户口上民族错了怎么办 改名字后行驶证怎么办 眼角撞到了肿了怎么办 想不想修真邪气怎么办 进户门比房间门低怎么办 吃了药反胃想吐怎么办 药吃了胃难受怎么办 吃了牙痛药胃痛怎么办 吃了药刺激胃怎么办 吃凉的刺激到胃怎么办 误食打农药的菜怎么办 狗把蛇咬死了怎么办 吃过毒死的狗怎么办 偷用室友东西被发现怎么办 室友看综艺太吵怎么办 被甲鱼咬住不放怎么办 凤仙叶子干焦怎么办 香槟开了没喝完怎么办