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 求出一 ...
随机推荐
- javaSE_07Java中类和对象-封装特性
一.谈谈什么是面向对象的思维 理解面向对象,重点是要思考以下的问题 面向过程 vs 面向对象 Ø 谈谈什么是面向过程的编程思想? Ø 为什么有面向过程还要有面向对象? Ø 谈谈什么是面向对象的编程思想 ...
- 咦,好像可以自己做个webapi框架了-IRouteHandler的使用
当我们学习到一定程度的时候,我们会想要去深入了解代码底层的东西,也更想拥有一个属于自己的框架,当然,博主也正是如此.本文可能成为编写一个webapi框架的开端.有研究MVC框架的朋友会发现,mvc框架 ...
- php 多条件查询
1.效果图如下: 点击提交后,把符合条件的筛选出来 2.代码: 逻辑:选中数据----以数组方式提交---拼接sql语句 难点: (1)从数据库里读取的数据要去重 (2)读取的数据是数组,要拼接 (3 ...
- MySQL5.7绿色版(免装版)的初始化和修改密码
1.下载MySQL5.7.18绿色版 1.1下载链接 以下是MySQL5.7.18绿色版的链接(来源oracle官网),打开链接直接下载 https://dev.mysql.com/gt/Downlo ...
- 使用hashCode()和equals()方法 - Java
在这篇文章中,我将指出我对hashCode()和equals()方法的理解.我将讨论它们的默认实现以及如何正确地覆盖它们.我还将使用Apache Commons包中的实用工具类来实现这些方法. has ...
- Filter自动登录
Dao层略过 Domain略过 Service层过 Web层 Select逻辑 获取表单数据,Web-service--Dao返回用户信息 如果返回不为null否则,重定向到登录页面.则判断用户是否勾 ...
- [Leetcode] DP -- Target Sum
You are given a list of non-negative integers, a1, a2, ..., an, and a target, S. Now you have 2 symb ...
- webpack的简单配置
本人刚开始也不会写webpack配置,刚开始在网上搜索了了一些,看的也是刚刚理解,所以准备自己写下来,已作纪念和贡献给像我一样不会配置的“童鞋”们! 1.创建webpack配置文件 在项目文件下创建一 ...
- Windows7下pip源配置修改
以下列举三种方式的pip源配置: 1. 设置环境变量PIP_CONFIG_FILE指向pip.ini源配置文件,pip.ini文件内容如下: [global] index-url = http://m ...
- SQL Server 文件结构 与 全局变量,函数
SQL Server 文件结构与全局变量 数据库和表 文件类型 主数据文件 .mdf 次要数据文件 .ndf 日志文件 .ldf 系统数据库 master 数据库 记录所有的登陆账户和系统配置设置 记 ...