Nyoj 修路方案(次小生成树)
- 描述
-
南将军率领着许多部队,它们分别驻扎在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题目改编
- 上传者
- 张云聪
题意:次小生成树
WA代码:
#include <vector>
#include <map>
#include <set>
#include <algorithm>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <string>
#include <cstring>
#include <queue>
using namespace std; #define MAX 200020
#define INF 0x3f3f3f3f struct edge
{
int x,y,cost;
int flag;
}; edge e[MAX];
int f[MAX];
int dis[MAX];
int v,n,m,ans; bool cmp(edge a,edge b)
{
return a.cost<b.cost;
} void init(int n)
{
for(int i=;i<=n;i++)
f[i]=i;
} int find(int x)
{
if(x!=f[x])
f[x]=find(f[x]);
return f[x];
} void Union(int x,int y)
{
x=find(x);
y=find(y);
f[y]=x;
} int same(int x,int y)
{
return find(x)==find(y);
} int kruskal_1(int n,int m)
{
int ans=;
for(int i=;i<m;i++)
{
if(!same(e[i].x,e[i].y))
{
e[i].flag=;
Union(e[i].x,e[i].y);
ans+=e[i].cost;
}
}
return ans;
} int kruskal_2(int n,int m)
{
int ans=,cnt=;
for(int i=;i<m;i++)
{
if (i == n)//除去这条边之后再求一次最小生成树
continue;
if(!same(e[i].x,e[i].y))
{
Union(e[i].x,e[i].y);
ans+=e[i].cost;
cnt++;
}
}
if(cnt!=n)
return -;
else
return ans;
} int main()
{
int t;
scanf("%d",&t);
while(t--){
init(n);
memset(e,,sizeof(e));
int v=;
scanf("%d%d",&n,&m);
int count;
for(int i=; i<m; i++){
scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].cost);
e[i].flag=;
}
sort(e,e+m,cmp);
int flag=,prim_2;
int prim_1=; prim_1=kruskal_1(n,m);
/*for(int i=0; i<m; i++){
cout<<e[i].x<<e[i].y<<e[i].cost<<e[i].flag<<endl;
}*/ for(int i=; i<m; i++){
if(e[i].flag==)
continue;
prim_2=;
init(n);
prim_2=kruskal_2(i,m);
if(prim_2==prim_1){
flag=;
break;
}
} if(prim_1==prim_2){
flag=;
} if(flag)
printf("Yes\n");
else
printf("No\n");
}
}
AC代码:
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
struct node
{
int u,v,val;
int flog;
}edge[+];
int pre[],m,n,minn;
void init()
{
for(int i=;i<;i++)
pre[i]=i;
}
int cmp(node s1,node s2)
{
return s1.val<s2.val;
}
int find(int x)
{
return pre[x]==x?x:pre[x]=find(pre[x]);
}
int F(int w)
{
int sum=;
for(int i=;i<m;i++)
{
if(i!=w)
{
int fx=find(edge[i].u);
int fy=find(edge[i].v);
if(fx!=fy)
{
pre[fx]=fy;
sum+=edge[i].val;
}
}
}
int s=find();//判断全部的点是不是已经全部连进去
for(int i=;i<=n;i++)
if(pre[i]!=s)
return -;
return sum;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
init();
scanf("%d%d",&n,&m);
for(int i=;i<m;i++)
scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].val),edge[i].flog=;
sort(edge,edge+m,cmp);
minn=;
for(int i=;i<m;i++)//找到最小生成树
{
int fx=find(edge[i].u);
int fy=find(edge[i].v);
if(fx!=fy)
{
pre[fx]=fy;
edge[i].flog=;//标记这条边在最小生成树中已经用过
minn+=edge[i].val;
}
}
int flag=;
for(int i=;i<m;i++)
{
if(edge[i].flog)//每次排除一条边
{
init();
if(F(i)==minn)
{
flag=;
break;
}
}
if(flag) break;
}
if(flag) printf("Yes\n");
else printf("No\n");
}
return ;
}
Nyoj 修路方案(次小生成树)的更多相关文章
- hdu4081 秦始皇修路(次小生成树)
题目ID:hdu4081 秦始皇修路 题目链接:点击打开链接 题目大意:给你若干个坐标,每个坐标表示一个城市,每个城市有若干个人,现在要修路,即建一个生成树,然后有一个魔法师可以免费造路(不消耗人 ...
- nyoj_118:修路方案(次小生成树)
题目链接 题意,判断次小生成树与最小生成树的权值和是否相等. 豆丁文档-- A-star和第k短路和次小生成树和Yen和MPS寻路算法 法一: 先求一次最小生成树,将这棵树上的边加入一个向量中,再判断 ...
- 修路方案 Kruskal 之 次小生成树
次小生成树 : Kruskal 是先求出来 最小生成树 , 并且记录下来所用到的的边 , 然后再求每次都 去掉最小生成树中的一个边 , 这样求最小生成树 , 然后看能不能得到 和原来最小生成树一样的 ...
- 修路方案(nyoj)
算法:次小生成树 描述 南将军率领着许多部队,它们分别驻扎在N个不同的城市里,这些城市分别编号1~N,由于交通不太便利,南将军准备修路. 现在已经知道哪些城市之间可以修路,如果修路,花费是多少. 现在 ...
- NYOJ 118 修路方案
修路方案 时间限制:3000 ms | 内存限制:65535 KB 难度:5 描述 南将军率领着许多部队,它们分别驻扎在N个不同的城市里,这些城市分别编号1~N,由于交通不太便利,南将军准备修 ...
- nyoj--118--修路方案(次小生成树)
修路方案 时间限制:3000 ms | 内存限制:65535 KB 难度:5 描述 南将军率领着许多部队,它们分别驻扎在N个不同的城市里,这些城市分别编号1~N,由于交通不太便利,南将军准备修路. ...
- nyoj 118 修路方案(最小生成树删边求多个最小生成树)
修路方案 时间限制:3000 ms | 内存限制:65535 KB 难度:5 描述 南将军率领着许多部队,它们分别驻扎在N个不同的城市里,这些城市分别编号1~N,由于交通不太便利,南将军准备修 ...
- hdu4081 次小生成树变形
pid=4081">http://acm.hdu.edu.cn/showproblem.php?pid=4081 Problem Description During the Warr ...
- HDU 4081 Qin Shi Huang's National Road System 次小生成树变种
Qin Shi Huang's National Road System Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/3 ...
随机推荐
- ffmpeg架构和解码流程分析
转 一,ffmpeg架构 1. 简介 FFmpeg是一个集录制.转换.音/视频编码解码功能为一体的完整的开源解决方案.FFmpeg的 开发是基于Linux操作系统,但是可以在大多数操作系统中编译和使用 ...
- C#读书
C#读书雷达 大家都知道,ThoughtWorks的技术雷达每年都会发布两到三次,它不但是业界技术趋势的标杆,更提供了一种卓有成效的方法论,即打造自己的技术雷达.在这种思想的驱动下,我们诞生了自己 ...
- ViewData ViewBag ViewModel
ViewBag 里可以携带dynamic的数据. Model 是从control传过来的模型数据. 我自己感觉ViewBag 可以携带少量的数据,但是我同事喜欢部分页partial 请求,ViewBa ...
- MySQLHA系列MHA(一)
MHA,这是Master High Availability Manager and Tools for MySQL,一个日本MySQL专家们使用Perl语言编写的一个脚本管理工具.该工具仅适用于My ...
- 条形码/二维码之开源利器ZXing图文介绍(转)
继前面介绍的一个日本开源软件(该软件只能实现QRCode)原文: Java实现二维码QRCode的编码和解码(http://sjsky.iteye.com/blog/1136934 ),今发现又一优秀 ...
- LeetCode——Add Binary
Given two binary strings, return their sum (also a binary string). For example, a = "11" b ...
- Eclipse4.4设备egit插件提交本地项目代码到远程仓库
一.设备egit 打开Eclipse的Marketplace.在搜索框中输入egit就可以,能够看到Eclipse4.4已经默认安装了egit,当然假设有新版本号的egit公布的话,也能够在下图上点击 ...
- Hibernate一个简短的引论
我们从几个方面进行阐述Hibernate When? What ? How? When? Hibernate由来是因为当时EJBBean1.1在处理entittBean架构时,花费的时间要比业务逻辑很 ...
- unity3d c# 产生真正的随机数
虽然能够使用Random类来生成随机数.但它是系统时钟种子,因此,有大量的反复产生伪随机数的. 您可以使用RNGCryptoServiceProvider();相对真随机数生成. 由加密服务提供程序( ...
- C# 使用WinRar命令压缩和解压缩
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.We ...