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 ...
随机推荐
- 安卓ButtomBar实现方法
这里ButtomBar有3个items,分别有icon和文字,在当前fragment时,所属的icon和文字会显示不同颜色. 1. 首先要准好ICON素材,命名规范要清楚. 2. 实现这个Buttom ...
- spring boot GlobalExceptionHandler @RestControllerAdvice @ExceptionHandler
package me.zhengjie.common.exception.handler; import lombok.extern.slf4j.Slf4j; import me.zhengjie.c ...
- Rails Create--params说明
参考:https://ruby-china.github.io/rails-guides/getting_started.html 表单提交后,其字段以参数形式传递给 Rails,然后就可以在控制器动 ...
- Vscode 下 PlantUML 插件的安装(windows and ubuntu)
目录 Windows 下安装 JAVA 安装环境配置: 测试 Ubuntu 16.04 下安装 Windows 下安装 Vscode graphviz PlantUML JAVA(推荐长期稳定版本,官 ...
- 对xgboost中dump_model生成的booster进行解析
xgboost原生包中有一个dump_model方法,这个方法能帮助我们看到基分类器的决策树如何选择特征进行分裂节点的,使用的基分类器有两个特点: 二叉树: 特征可以重复选择,来切分当前节点所含的数据 ...
- LIS 问题 二分查找优化
按n=5,a-{4,2,3,1,5}为例 dp的值依次是: INF INF INF INF INF 4 INF INF INF INF 2 INF INF INF INF 2 ...
- [LC] 47. Permutations II
Given a collection of numbers that might contain duplicates, return all possible unique permutations ...
- OpenGL 保存bmp图像
今天我们先简单介绍Windows中常用的BMP文件格式,然后讲OpenGL的像素操作.虽然看起来内容可能有点多,但实际只有少量几个知识点,如果读者对诸如”显示BMP图象”等内容比较感兴趣的话,可能不知 ...
- 升级mongodb数据库2.6.6到3.0.3,切换引擎,主从同步数据
只升级mongodb的版本极为简单,更新/替换 bin/目录下的可执行文件即可. debian和osx上的升级,按步骤来,没什么好说的. http://docs.mongodb.org/manual/ ...
- rancher2.0快速入门
注意:本入门指南的目的是让您快速的运行一个Rancher2.0环境,它不适用于生产.有关更全面的说明,请查阅Rancher安装. 本教程将指导您完成: 安装Rancher v2.0 : 创建第一个集群 ...