nyoj_118:修路方案(次小生成树)
题意,判断次小生成树与最小生成树的权值和是否相等。
豆丁文档—— A-star和第k短路和次小生成树和Yen和MPS寻路算法
法一:
先求一次最小生成树,将这棵树上的边加入一个向量中,再判断去掉前面所求的最小生成树的某条边能否再求得一棵等权值的最小生成树
复杂度O(NElogE)
//稠密图不可用
#include<bits/stdc++.h>
using namespace std;
+ ;
+ ;
int fa[maxn];
int n, m;
vector<int> TreeEdge;
struct Road //保存每条路的信息
{
int u,v,w;
bool operator<(const Road& t) const //按长度由小到大排序
{
return w<t.w;
}
} R[maxm];
//初始化并查集
void Init()
{
; i <= n; i++)
fa[i]=i; //每个点自成一个连通分量
}
//找x的祖先
int Find(int x)
{
return x == fa[x]? x:fa[x]=Find(fa[x]);
}
//判断图的连通性
bool isAccess()
{
);
; i <= n; i++)
if(f!=Find(i)) return false;
return true;
}
//kruskal求不要k这条边的最小生成树
int kruskal(int k)
{
;
Init();
; i<m; i++)
{
if(i!=k)
{
int tx=Find(R[i].u);
int ty=Find(R[i].v);
if(tx!=ty)
{
ans+=R[i].w;
fa[tx]=ty;
}
}
}
if(isAccess()) return ans; //如果是生成树,返回权值
;
}
int main()
{
int t;
scanf("%d", &t);
while (t--)
{
TreeEdge.clear();
scanf("%d%d",&n,&m);
; i<m; i++)
scanf("%d%d%d",&R[i].u,&R[i].v,&R[i].w);
sort(R, R+m); //将所有边排序
Init();
//===begin===MST
; //求最小生成树
; i<m; i++)
{
int tx=Find(R[i].u), ty=Find(R[i].v);
if(tx!=ty)
{
ans+=R[i].w;
fa[tx]=ty;
TreeEdge.push_back(i);//将这条边加入生成树中
}
}
//===end===MST
;
;i<TreeEdge.size();i++)
if(kruskal(TreeEdge[i])==ans) //看看不用这条边能否再次生成一棵最小生成树
{
ok=;
break;
}
if(ok) printf("Yes\n");
else printf("No\n");
}
}
法二:
首先求出原图的最小生成树,记录权值之和为Minst.枚举添加每条不在最小生成树上的边<u,v>,加上以后一定会形成一个环,找到环上权值第二大的边(即除<u,v>外最大的边)把它删除掉,计算当前生成树的权值之和。取所有枚举修改的生成树权值之和的最小值,就是次小生成树。具体实现时,更简单的方法是从每个节点i遍历整个最小生成树,定义F[i,j]为从i到j的路径上最大边的权值。遍历图求出F[i,j]的值,然后对于添加每条不在最小生成树中的边<i,j>,新的生成树权值之和就是Minst+w<i,j>-F[j],记录其最小值,则为次小生成树。该算法的时间复杂度为O(n^2+m)。由于只用求一次最小生成树,可以用最简单的Prim算法,时间复杂度为O(n^2)。算法的瓶颈不在于最小生成树,而在于O(n^2+m)的枚举加边修改,所以用更好的最小生成树算法是没有必要的。(详见豆丁文档)
复杂度O(n^2)
标程如下:
#include<bits/stdc++.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));
; i<=N; i++)
dis[i]=map[][i],pre[i]=;
vis[]=true;
; j<N; j++)
{
minn=MAX;
; i<=N; i++)
if(!vis[i]&&dis[i]<minn)
k=i,minn=dis[i];
pr=pre[k];
maxlen[k][pr]=maxlen[pr][k]=map[k][pr];
; i<=N; i++)
if(vis[i])
maxlen[i][k]=maxlen[k][i]=max(maxlen[i][pr],maxlen[k][pr]);
vis[k]=true;
; i<=N; i++)
if(!vis[i]&&dis[i]>map[i][k])
{
dis[i]=map[i][k];
pre[i]=k;
}
}
; i<N; i++)
; j<=N; j++)
if(pre[i]==j||pre[j]==i)continue;
;
;
}
int main()
{
int T;scanf("%d",&T);
while(T--)
{
int u,v,w;
scanf("%d%d",&N,&M);
; i<=N; i++)
; j<=N; j++)
{
map[i][j]=MAX;
maxlen[i][j]=MIN;
}
; 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");
}
}
nyoj_118:修路方案(次小生成树)的更多相关文章
- Nyoj 修路方案(次小生成树)
描述 南将军率领着许多部队,它们分别驻扎在N个不同的城市里,这些城市分别编号1~N,由于交通不太便利,南将军准备修路. 现在已经知道哪些城市之间可以修路,如果修路,花费是多少. 现在,军师小工已经找到 ...
- hdu4081 秦始皇修路(次小生成树)
题目ID:hdu4081 秦始皇修路 题目链接:点击打开链接 题目大意:给你若干个坐标,每个坐标表示一个城市,每个城市有若干个人,现在要修路,即建一个生成树,然后有一个魔法师可以免费造路(不消耗人 ...
- 修路方案 Kruskal 之 次小生成树
次小生成树 : Kruskal 是先求出来 最小生成树 , 并且记录下来所用到的的边 , 然后再求每次都 去掉最小生成树中的一个边 , 这样求最小生成树 , 然后看能不能得到 和原来最小生成树一样的 ...
- nyoj--118--修路方案(次小生成树)
修路方案 时间限制:3000 ms | 内存限制:65535 KB 难度:5 描述 南将军率领着许多部队,它们分别驻扎在N个不同的城市里,这些城市分别编号1~N,由于交通不太便利,南将军准备修路. ...
- 修路方案(nyoj)
算法:次小生成树 描述 南将军率领着许多部队,它们分别驻扎在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 ...
- 【次小生成树】bzoj1977 [BeiJing2010组队]次小生成树 Tree
Description 小 C 最近学了很多最小生成树的算法,Prim 算法.Kurskal 算法.消圈算法等等. 正当小 C 洋洋得意之时,小 P 又来泼小 C 冷水了.小 P 说,让小 C 求出一 ...
随机推荐
- a标签点击之后有个虚线边框,怎么去掉
1.行内处理方式1 <a hidefocus="true" href="#"></a> 2.行内处理方式2,让a标签获得焦点就失去焦点, ...
- Unexpected end of input 和 Unexpected token var 和 Unexpected token ;
在写jsp的时候使用的一段代码一直调试,出现Unexpected token ; 错误. 所以最后把代码各种精简,得到了如下的测试示例代码 <% String aaa="123&quo ...
- 深入研究React setState的工作机制
前言 上个月发表了一篇 React源码学习--ReactClass,但是后来我发现,大家对这种大量贴代码分析源码的形式并不感冒.讲道理,我自己看着也烦,还不如自己直接去翻源码来得痛快.吸取了上一次的教 ...
- cookie的路径问题
今天公司网站(不考虑跨域访问情况)有个需求就是在一个路径下存一个cookie 比如这样 www.fdf.com/vichain/dashback/myback 在这个目录下存放一个cookie 在这 ...
- 没有main方法真的不能执行代码了吗?
今天看北大慕课遇到一段代码,于是下载下来跑了一下,奇葩的是,没有main方法既没报错,还出了结果. 下面贴出代码: class InitialTest { public static void mai ...
- Primeton BPS 6.7+MyEclipse_5.5.1GA_E3.2.2插件安装
准备 Primeton_BPS_6.7_Developer MyEclipse5.5插件版 BPS安装 MyEclipse插件安装 点击MyEclipse_5.5.1GA_E3.2.2_Install ...
- AngularJS高级程序设计读书笔记 -- 过滤器篇
一. 过滤器基础 过滤器用于在视图中格式化展现给用户的数据. 一旦定义过滤器之后, 就可在整个模块中全面应用, 也就意味着可以用来保证跨多个控制器和视图之间的数据展示的一致性. 过滤器将数据在被指令处 ...
- 为什么使用bootstrap在一个页面同时做两个轮播效果时,只有第一个有效??
我们都知道使用bootstrap做轮播效果非常快,但是有时候一个页面会需要两个轮播:但这个时候再次使用bootstrap做轮播效果时就会失效:原因在于bootstrap的Carousel问题,只要修改 ...
- java http请求,字节流获取百度数据
请求的地址为: http://api.map.baidu.com/place/v2/search?&q=%E9%A5%AD%E5%BA%97®ion=%E9%87%8D%E5%B ...
- 安装Dubbo注册中心(Zookeeper-3.4.6)
样例视频教程:http://www.roncoo.com/course/view/f614343765bc4aac8597c6d8b38f06fd Dubbo建议使用Zookeeper作为服务的注册中 ...