UVA - 10462 Is There A Second Way Left?
题意:
给你一张无向图,让你判断三种情况:1.不是连通图(无法形成生成树)2.只能生成唯一的生成树 3.能生成的生成树不唯一(有次小生成树),这种情况要求出次小生成树的边权值和。
思路:
比较常见的次小生成树做法:先求出最小生成树,再依次使用不在最小生成树上的边与最小生成树连接,连接后必然出现且仅出现一个环(由于生成树上的任意两点之间都有唯一的一条路径,且图中所有的点都在生成树上),将这条边与环上除了这条边权值最大的边替换,就形成了新的生成树,在不断尝试新边的过程中维护一个最小的生成树的边权值和即是次小生成树的边权值和。
可以发现生成的环形成的路径即是两个端点与它们的LCA(最近公共祖先)的路径,所以可以用求LCA的办法顺便记录路径中边权的最大值。
代码:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
typedef long long ll;
using namespace std; const int N=1e2+; struct edge {
int id;
int from;
int to;
int val;
}E[N<<]; struct cmp {
bool operator()(edge a,edge b) {
return a.val>b.val;
}
}; int fir[N],nex[N<<],cnt;
int pre[N],dis[N],dep[N];
bool vis[N],used[N<<];
int T=,t,n,m,cost; void init() {
memset(fir,-,sizeof(fir));
cost=cnt=;
} void connect(int from,int to,int val,int id) {
E[cnt]=(edge){id,from,to,val};
nex[cnt]=fir[from];
fir[from]=cnt++;
E[cnt]=(edge){id,to,from,val};
nex[cnt]=fir[to];
fir[to]=cnt++;
} bool prim() {
int node=;//记录生成树上的点的数量。
memset(vis,false,sizeof(vis));
memset(used,false,sizeof(used));
priority_queue <edge,vector <edge>,cmp> Q;
Q.push((edge){-,,,});
dep[]=;
while(!Q.empty()) {
edge q=Q.top();
Q.pop();
if(vis[q.to]) continue;
vis[q.to]=true;
cost+=q.val; node++;
pre[q.to]=q.from;
dis[q.to]=q.val;
dep[q.to]=dep[q.from]+;//在求最小生成树的过程中顺便记录生成树上的点的深度以及父节点、与父节点连接的边的权值。
used[q.id]=true;//记录哪些边在最小生成树上,到时在求次小生成树的过程中跳过这些边。
for(int i=fir[q.to];i!=-;i=nex[i]) {
int to=E[i].to;
if(!vis[to]) Q.push(E[i]);
}
}
if(node<n) return false;//生成树上的点少于n,说明不是连通图,无法形成最小生成树。
return true;
} int lca(int x,int y) {
int MAX=;
if(dep[x]>dep[y]) swap(x,y);
while(dep[y]>dep[x]) {
MAX=max(MAX,dis[y]);
y=pre[y];
}
while(x!=y) {
MAX=max(MAX,dis[y]);
y=pre[y];
MAX=max(MAX,dis[x]);
x=pre[x];
}
return MAX;
} void solve() {
bool flag=false;
int second=2e9;
for(int i=;i<cnt;i+=) {
if(used[E[i].id]) continue;
flag=true;
second=min(second,cost+E[i].val-lca(E[i].from,E[i].to));
}
if(flag) printf("Case #%d : %d\n",++T,second);//若除了最小生成树上的边以外没有剩下的边,那么没有次小生成树。
else printf("Case #%d : No second way\n",++T);
} int main() {
scanf("%d",&t);
while(t--) {
scanf("%d%d",&n,&m);
init();
for(int i=;i<=m;i++) {
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
connect(x,y,z,i);
}
if(!prim()) {
printf("Case #%d : No way\n",++T); continue;
}
solve();
}
return ;
}
UVA - 10462 Is There A Second Way Left?的更多相关文章
- UVA 10462 Is There A Second Way Left? 次小生成树
模板题 #include <iostream> #include <algorithm> #include <cstdio> #include <cstdli ...
- UVA 10462 Is There A Second Way Left?(次小生成树&Prim&Kruskal)题解
思路: Prim: 这道题目中有重边 Prim可以先加一个sec数组来保存重边的次小边,这样不会影响到最小生成树,在算次小生成树时要同时判断次小边(不需判断是否在MST中) Kruskal: Krus ...
- UVA 10462 —— Is There A Second Way Left?——————【最小生成树、kruskal、重边】
Nasa, being the most talented programmer of his time, can’t think things to be so simple. Recently a ...
- UVA 10462 Is There A Second Way Left? (次小生成树+kruskal)
题目大意: Nasa应邻居们的要求,决定用一个网络把大家链接在一起.给出v个点,e条可行路线,每条路线分别是x连接到y需要花费w. 1:如果不存在最小生成树,输出“No way”. 2:如果不存在次小 ...
- UVA - 10462-Is There A Second Way Left? Kruskal求次小生成树
UVA - 10462 题意: 求次小生成树的模板题,这道题因为有重边的存在,所以用kruskal求比较好. #include <iostream> #include <cstdio ...
- [kuangbin带你飞]专题八 生成树 - 次小生成树部分
百度了好多自学到了次小生成树 理解后其实也很简单 求最小生成树的办法目前遇到了两种 1 prim 记录下两点之间连线中的最长段 F[i][k] 之后枚举两点 若两点之间存在没有在最小生成树中的边 那么 ...
- KUANGBIN带你飞
KUANGBIN带你飞 全专题整理 https://www.cnblogs.com/slzk/articles/7402292.html 专题一 简单搜索 POJ 1321 棋盘问题 //201 ...
- kuangbin带你飞 生成树专题 : 次小生成树; 最小树形图;生成树计数
第一个部分 前4题 次小生成树 算法:首先如果生成了最小生成树,那么这些树上的所有的边都进行标记.标记为树边. 接下来进行枚举,枚举任意一条不在MST上的边,如果加入这条边,那么肯定会在这棵树上形成一 ...
- [kuangbin带你飞]专题1-23题目清单总结
[kuangbin带你飞]专题1-23 专题一 简单搜索 POJ 1321 棋盘问题POJ 2251 Dungeon MasterPOJ 3278 Catch That CowPOJ 3279 Fli ...
随机推荐
- Matlab高级教程_第二篇:Matlab相见恨晚的模块_02_并行运算-2
1 MATLAB并行计算-从个人桌面到远程集群和云(陈伟/魏奋)视频摘录笔记 https://cn.mathworks.com/videos/parallel-computing-with-matla ...
- Nmap_使用介绍
Nmap 注意,本文仅是作为课余时间的学习了解,请不要做有关违反法律法规的事情,违者自行承担后果!!! 环境centos7.7yum -y install nmap 命令操作 1.扫描单个目标 1. ...
- mysql绿色版小白简易安装教程
第一步,解压并安装mysql 我们先解压整个安装包 然后进入解压后的安装包 复制安装包路径 然后按Windows键,打开"开始",输入cmd 接着以管理员方式打开cmd 如图 接着 ...
- 系统学习javaweb3----HTML语言3(结束)
说明:昨天是北方小年,需要做的事情有点多,需要祭灶,扫尘.包饺子,吃糖瓜儿,学习时间有点少,所以今天将两天的知识综合一下发出. 自我感觉:虽然感觉大致都了解了HTML语言,但是感觉自己面对程序还是无从 ...
- GSON转换成Long型变为科学计数法及时间格式转换异常的解决方案
直接上工具类了,简单实用 public class GsonUtils { private static Gson gson = null; static { if (gson == null) { ...
- 什么是CDN
1.什么是cdn cdn全称是内容分发网络.其目的是让用户能够更快速的得到请求的数据.简单来讲,cdn就是用来加速的,他能让用户就近访问数据,这样就更更快的获取到需要的数据.举个例子,现在服务器 ...
- Centos-Apache服务(2)
title date tags layout CentOS6.5 Apache的增值服务 2018-09-03 Centos6.5服务器搭建 post 1.更改Apache的监听端口号 [root@l ...
- Archives: 2018/11
There are 35 posts in total till now. 11月 11, 2018 HTTP 11月 11, 2018 TCP与UDP 11月 10, 2018 Python测试 1 ...
- 吴裕雄--天生自然Android开发学习:下载安装android stuio集成开发工具
下载链接: https://developer.android.google.cn/index.html
- java异常分析;剖析printStackTrace和fillInStackTrace
Java异常的栈轨迹(Stack Trace) 捕获到异常时,往往需要进行一些处理.比较简单直接的方式就是打印异常栈轨迹Stack Trace.说起栈轨迹,可能很多人和我一样,第一反应就是printS ...