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 ...
随机推荐
- 使用OkHttp上传图片到服务器
Okhttp上传图片方法,就像网页那样,使用Form的Post. 首先创建requestBody,然后Builder构建Query:最后Response返回服务器请求,最后把response.body ...
- VisitsService
package me.zhengjie.monitor.domain; import lombok.Data; import org.hibernate.annotations.CreationTim ...
- springboot shiro ehcache redis 简单使用
引入相关pom <dependency> <groupId>org.springframework.boot</groupId> <artifactId> ...
- Nearby Bicycles
With fast developments of information and communication technology, many cities today have establish ...
- php启动后netstat看不到9000端口的问题
https://www.cnblogs.com/jonsea/p/5522018.html php-fpm配置文件详解 其实就是PHP配置文件改一个参数 listen = 127.0.0.1: ...
- Exchange Online合规性管理
一.就地电子数据展示和保留 就地电子数据展示允许组织内的授权合规性管理员搜索整个Exchange组织的邮箱数据.预览搜索结果,并可以复制到发现邮箱将其导出到以pst为拓展名的文件. 就地电子数据展示使 ...
- Yii框架的学习指南(策码秀才篇)1-2 一步步学习yii framework
我也是新手,不过之前学习了tp和ci框架,所以尝鲜想看看yii到底有多强大. 如何新建一个webapp(网站应用)呢,下面是2个步骤: 1. cmd 切换到htdocs下面的yii目录下的framew ...
- 用go写爬虫服务并发请求,限制并发数
java写爬虫服务,思路是线程池,任务队列,限制并行线程数即可. go要用另一种设计思路,不能在线程层面限制,协程的异步请求,如果不作处理,并行发出所有网络请求,因网络请求数过多,会抛出异常 低版本的 ...
- Mybatis与Spring整合(纯注解)
java1.5版本之后开始支持注解,spring*2开始提供注解配置方式,到spring**4后spring推荐使用注解配置 IOC注解(主要作用就是在spring容器中声明一个Bean,同xml中的 ...
- ajax异步的加深理解
过去印象中的ajax的异步操作,一直还居然在$.ajax函数内部的异步,真是大错特错,实际的异步操作,是针对整个js文件来的. 今天总算意识到了,实际情况如下: $(function(){ //[弹框 ...