NYOJ 118 修路方案
修路方案
- 描述
- 
南将军率领着许多部队,它们分别驻扎在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)
- 样例输入
- 
2 
 3 3
 1 2 1
 2 3 2
 3 1 3
 4 4
 1 2 2
 2 3 2
 3 4 2
 4 1 2
- 样例输出
- 
No 
 Yes
- 来源
- POJ题目改编
- 上传者
- 张云聪
- 
解题:次小生成树,搞了好久,好多文档看不懂啊。。。只好学点奇葩的东西,走点旁门左道了。。。。。弱菜有弱菜的学习方法。。。 这是什么算法。。。?好吧。。。偷学于豆丁上一篇文章<<A-star和第k短路和次小生成树和Yen和MPS寻路算法>> 首先求出原图的最小生成树,记录权值之和为Minst.枚举添加每条不在最小生成树上的边<u,v>,加上以后一定会形成一个环,找到环上权值第二大的边(即除<u,v>外最大的边)把它删除掉,计算当前生成树的权值之和。取所有枚举修改的生成树权值之和的最小值,就是次小生成树。具体实现时,更简单的方法是从每个节点i遍历整个最小生成树,定义F[j]为从i到j的路径上最大边的权值。遍历图求出F[j]的值,然后对于添加每条不在最小生成树中的边<i,j>,新的生成树权值之和就是Minst-w<i,j>-F[j],记录其最小值,则为次小生成树。该算法的时间复杂度为O(n^2+m)。由于只用求一次最小生成树,可以用最简单的Prim算法,时间复杂度为O(n^2)。算法的瓶颈不在于最小生成树,而在于O(n^2+m)的枚举加边修改,所以用更好的最小生成树算法是没有必要的。 #include <iostream> 
 #include <cstdio>
 #include <cstring>
 #include <cstdlib>
 #include <vector>
 #include <climits>
 #include <algorithm>
 #include <cmath>
 #define LL long long
 #define INF 0x3f3f3f
 using namespace std;
 struct arc {
 int u,v,w;
 } e[];
 int mp[][],d[],pre[],uf[];
 int n,m;
 bool vis[];
 bool cmp(const arc &x,const arc &y){
 return x.w < y.w;
 }
 int findF(int x){
 if(x != uf[x])
 uf[x] = findF(uf[x]);
 return uf[x];
 }
 int kruskal(){
 int i,j,ans = ;
 for(i = ; i <= n; i++){
 uf[i] = i;
 pre[i] = -;
 }
 memset(vis,false,true);
 for(i = ; i < m; i++){
 int x = findF(e[i].u);
 int y = findF(e[i].v);
 if(x != y){
 uf[x] = y;
 ans += e[i].w;
 pre[e[i].v] = e[i].u;
 vis[i] = true;
 }
 }
 return ans;
 }
 int main() {
 int ks,i,j,Minst,mx,u,v;
 bool flag;
 scanf("%d",&ks);
 while(ks--) {
 scanf("%d%d",&n,&m);
 for(i = ; i < m; i++) {
 scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w);
 if(e[i].u > e[i].v) swap(e[i].u,e[i].v);
 mp[e[i].u][e[i].v] = mp[e[i].v][e[i].u] = e[i].w;
 }
 sort(e,e+m,cmp);
 Minst = kruskal();
 flag = false;
 for(i = ; i < m; i++){
 if(!vis[i]){
 mx = ;
 u = e[i].u;
 v = e[i].v;
 while(pre[v] != u && pre[v] != -){
 if(mp[v][pre[v]] > mx) mx = mp[v][pre[v]];
 v = pre[v];
 }
 if(mx == e[i].w){
 flag = true;break;
 }
 }
 }
 flag?puts("Yes"):puts("No");
 }
 return ;
 }别人写的Prim算法版的次小生成树 #include <iostream> 
 #include <stdio.h>
 #include <string.h>
 using namespace std;
 #define maxN 510
 #define MAX 0x0fffffff
 #define MIN -0x0fffffff
 int N,M,map[maxN][maxN],dis[maxN],maxlen[maxN][maxN],pre[maxN];
 bool vis[maxN];
 int prim() {
 int i,j,k,minn,pr;
 memset(vis,false,sizeof(vis));
 for(i=; i<=N; i++) {
 dis[i]=map[][i];
 pre[i]=;
 }
 vis[]=true;
 for(j=; j<N; j++) {
 minn = MAX;
 for(i=; i <= N; i++)
 if(!vis[i] && dis[i]<minn) {
 minn=dis[k=i];
 }
 pr = pre[k];
 maxlen[k][pr] = maxlen[pr][k] = map[k][pr];
 for(i = ; i <= N; i++)
 if(vis[i])
 maxlen[i][k]=maxlen[k][i]=max(maxlen[i][pr],maxlen[pr][k]);
 vis[k]=true;
 for(i=; i<=N; i++)
 if(!vis[i]&&dis[i]>map[k][i]) {
 dis[i]=map[i][k];
 pre[i]=k;
 }
 }
 for(i=; i < N; i++)
 for(j = i+; j <= N; j++)
 if(pre[i] == j|| pre[j] == i) continue;
 else if(maxlen[i][j] == map[i][j]) return ;
 return ;
 }
 int main() {
 int T;
 scanf("%d",&T);
 while(T--) {
 int u,v,w;
 scanf("%d%d",&N,&M);
 for(int i = ; i <= N; i++)
 for(int j=; j <= N; j++) {
 map[i][j] = MAX;
 maxlen[i][j] = MIN;
 }
 for(int i = ; i < M; i++) {
 scanf("%d%d%d",&u,&v,&w);
 map[u][v]=map[v][u]=w;
 }
 if(prim())printf("Yes\n");
 else printf("No\n");
 }
 return ;
 }
NYOJ 118 修路方案的更多相关文章
- nyoj 118 修路方案(最小生成树删边求多个最小生成树)
		修路方案 时间限制:3000 ms | 内存限制:65535 KB 难度:5 描述 南将军率领着许多部队,它们分别驻扎在N个不同的城市里,这些城市分别编号1~N,由于交通不太便利,南将军准备修 ... 
- NYOJ 118 路方案(第二小的跨越)
		修路方案 时间限制:3000 ms | 内存限制:65535 KB 难度:5 描写叙述 南将军率领着很多部队,它们分别驻扎在N个不同的城市里,这些城市分别编号1~N.因为交通不太便利,南将军准备修 ... 
- 修路方案(nyoj)
		算法:次小生成树 描述 南将军率领着许多部队,它们分别驻扎在N个不同的城市里,这些城市分别编号1~N,由于交通不太便利,南将军准备修路. 现在已经知道哪些城市之间可以修路,如果修路,花费是多少. 现在 ... 
- Nyoj  修路方案(次小生成树)
		描述 南将军率领着许多部队,它们分别驻扎在N个不同的城市里,这些城市分别编号1~N,由于交通不太便利,南将军准备修路. 现在已经知道哪些城市之间可以修路,如果修路,花费是多少. 现在,军师小工已经找到 ... 
- nyoj_118:修路方案(次小生成树)
		题目链接 题意,判断次小生成树与最小生成树的权值和是否相等. 豆丁文档-- A-star和第k短路和次小生成树和Yen和MPS寻路算法 法一: 先求一次最小生成树,将这棵树上的边加入一个向量中,再判断 ... 
- 修路方案    Kruskal 之 次小生成树
		次小生成树 : Kruskal 是先求出来 最小生成树 , 并且记录下来所用到的的边 , 然后再求每次都 去掉最小生成树中的一个边 , 这样求最小生成树 , 然后看能不能得到 和原来最小生成树一样的 ... 
- nyoj--118--修路方案(次小生成树)
		修路方案 时间限制:3000 ms | 内存限制:65535 KB 难度:5 描述 南将军率领着许多部队,它们分别驻扎在N个不同的城市里,这些城市分别编号1~N,由于交通不太便利,南将军准备修路. ... 
- DP:Making the Grade(POJ 3666)
		聪明的修路方案 题目大意:就是农夫要修一条路,现在要求这条路要么就是上升的,要么就是下降的,总代价为∑|a[i]-b[i]|,求代价最低的修路方案, (0 ≤ β≤ 1,000,000,000) , ... 
- 最小生成树模板题  hpu 积分赛 Vegetable and Road again
		问题 H: Vegetable and Road again 时间限制: 1 Sec 内存限制: 128 MB 提交: 19 解决: 8 题目描述 修路的方案终于确定了.市政府要求任意两个公园之间都必 ... 
随机推荐
- nopCommerce - asp.net开源商城
			nopcommerce官网 http://nopcommerce.codeplex.com/ nopCommerce is a open source e-commerce solution that ... 
- CF1043D Mysterious Crime
			思路: 参考了http://codeforces.com/blog/entry/62797,把第一个序列重标号成1,2,3,...,n,在剩下的序列中寻找形如x, x + 1, x + 2, ...的 ... 
- nodejs中的异步回调机制
			1.再次clear Timer定时器的作用 setTimeOut绝非是传统意义上的“sleep”功能,它做不到让主线程“熄火”指定时间,它是用来指定:某个回调在固定时间后插入执行栈!(实际执行时间略长 ... 
- 自动完成文本框(AutoCompleteTextView与MultiAutoCompleteTextView)关联适配器
			<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools=&q ... 
- Vivado增量式编译
			Vivado 中的增量设计会重新利用已有的布局布线数据来缩短运行时间,并生成可预测的结果.当设计有 95% 以上的相似度时,增量布局布线的运行时间会比一般布局布线平均缩短2倍.若相似度低于80%,则使 ... 
- Java文件操作系列[3]——使用jacob操作word文档
			Java对word文档的操作需要通过第三方组件实现,例如jacob.iText.POI和java2word等.jacob组件的功能最强大,可以操作word,Excel等格式的文件.该组件调用的的是操作 ... 
- PHP识别二维码功能,php-zbarcode 安装
			php-zbarcode是PHP识别二维码的扩展. 下面是安装方法,安装前要先安装ImageMagick.zbar. php-zbarcode 下载地址 安装ImageMagick: yum inst ... 
- (十)mybatis之配置(mybatis-config.xml)
			配置 可以从前篇的文章中知道(https://www.cnblogs.com/NYfor2018/p/9093472.html ),要使用mybatis需要以下配置: 1. mybatis-con ... 
- Python学习日志9月16日
			刚才我差点睡着了,差资料的时候太费神,有些累. 今天早晨学习了<head first HTML and CSS>,今天把昨天没看了的关于字体和颜色的一章节看完了,真长.我详细的做了笔记,并 ... 
- 文本编辑器vim/vi用法完全解读
			vi用法 1.启动vim 2.命令模式和输入模式 3.退出vi 4.vi与ex命令 5.移动光标 6.跳转 7.搜索 8.插入文本 9.修改文本 10.替换文本 11.删除文本 12.恢复和撤销改变 ... 
