nyoj118 修路方案(求次小生成树)
来源:互联网 发布:jquery 遍历数组对象 编辑:程序博客网 时间:2024/05/01 23:52
修路方案
时间限制:3000 ms | 内存限制:65535 KB
难度:5
- 描述
南将军率领着许多部队,它们分别驻扎在N个不同的城市里,这些城市分别编号1~N,由于交通不太便利,南将军准备修路。
现在已经知道哪些城市之间可以修路,如果修路,花费是多少。
现在,军师小工已经找到了一种修路的方案,能够使各个城市都联通起来,而且花费最少。
但是,南将军说,这个修路方案所拼成的图案很不吉利,想让小工计算一下是否存在另外一种方案花费和刚才的方案一样,现在你来帮小工写一个程序算一下吧。
- 输入
- 第一行输入一个整数T(1<T<20),表示测试数据的组数
每组测试数据的第一行是两个整数V,E,(3<V<500,10<E<200000)分别表示城市的个数和城市之间路的条数。数据保证所有的城市都有路相连。
随后的E行,每行有三个数字A B L,表示A号城市与B号城市之间修路花费为L。 - 输出
- 对于每组测试数据输出Yes或No(如果存在两种以上的最小花费方案则输出Yes,如果最小花费的方案只有一种,则输出No)
- 样例输入
23 31 2 12 3 23 1 34 41 2 22 3 23 4 24 1 2
- 样例输出
NoYes
- 来源
- POJ题目改编
- 上传者
- 张云聪
对于最小生成树(可以用kruskal和prime算法求得,在这里我是用kruskal求得,如果不会请自己百度。),边的权值的和最小称为最小生成树。
而次小生成树就是除了最小生成树外的最小生成树。而且所有的次小生成树都是通过最小生成树的换边得到的。
所以难点就是如何换边。
对于如何换边:
1.先求出最小生成树,值为x。
2.一一枚举添加不在生成树上的边(这时候一定形成了一个环)
3.寻找环上的(最小生成树上的边)权值最大值与你所添加不在生成树上的边的权值比较,所得到的差值为min。
由于是一一枚举添加边,min有多个,求出最小的哪一个,所以次小生成树就为x+min。
所以对于这道题也就很简单了,只要min=0就代表有多种方案了。具体请看代码:
#include <stdio.h>#include <string.h>#include <algorithm>using namespace std;struct node{int a,b,c,vis;}c[200005];int fa[505],v,e,stamp[505][505],visit[505];bool cmp(node a,node b){return a.c<b.c;}int find(int x){if(fa[x]!=x) fa[x]=find(fa[x]);return fa[x];}void init(){for(int i=1;i<=v;i++)fa[i]=i;}void comb(int x1,int x2,int cost)//存贮最小生成树的边{stamp[x1][x2]=stamp[x2][x1]=cost;}int sec_find(int x,int y,int min)//换边{if(x==y)return min;for(int i=1;i<=v;i++){if(stamp[x][i]&&!visit[i]){visit[x]=1;if(stamp[x][i]>min)min=stamp[x][i];sec_find(i,y,min);}}return min;}int main(){int ncase,mintree,sec;scanf("%d",&ncase);while(ncase--){memset(stamp,0,sizeof(stamp));memset(visit,0,sizeof(visit));scanf("%d %d",&v,&e);init();for(int i=0;i<e;i++)scanf("%d %d %d",&c[i].a,&c[i].b,&c[i].c);sort(c,c+e,cmp);int mintree=0;for(int i=0;i<e;i++)//求最小生成树{int x1=find(c[i].a);int x2=find(c[i].b);if(x1!=x2)fa[x1]=x2,mintree+=c[i].c,c[i].vis=1,comb(x1,x2,c[i].c);elsec[i].vis=0;//对于不在最小生成树里面的边标记一下}int flag=0;for(int i=0;i<e;i++)if(!c[i].vis)//最小生成树之外的边{sec=sec_find(c[i].a,c[i].b,-1000000);if(sec==c[i].c){flag=1;break;}}if(flag)printf("Yes\n");elseprintf("No\n");}return 0;}
1 0
- nyoj118 修路方案(求次小生成树)
- NYOJ118 修路方案(次小生成树)
- nyoj118修路方案(次小生成树)
- NYOJ118 修路方案 次小生成树
- NYOJ118 修路方案 次小生成树Prim
- nyoj118 修路方案之次小生成树
- NYOJ118 修路方案
- 修路方案(次小生成树)
- 修路方案(次小生成树)
- 修路方案(次小生成树)
- NYOJ 修路方案(次小生成树)
- NYOJ 118 修路方案 (次小生成树--prime)
- nyoj 118 修路方案(次小生成树)
- nyoj--118--修路方案(次小生成树)
- NYOJ修路方案【次小生成树】
- nyoj 修路方案 次小生成树
- 最小生成树(修路)
- 修路方案 【最小生成树变形】-- 次小生成树
- DistributedCache的使用
- C语言基础———指针,结构体指针,函数指针
- wince 自动启动程序设置
- springmvc拦截器使用
- POJ 3168 Barn Expansion (几何+排序)
- nyoj118 修路方案(求次小生成树)
- printf输出字体颜色
- 可以使电脑更加顺手的软件以及设置(个人习惯)
- 观察者模式
- C语言基础之--------内存地址分配
- js获取项目的各个路径
- Java连接MQ的实例
- 内存泄漏检测
- linux kernel 网络协议栈之xps特性详解