题意:

给你一张无向图,让你判断三种情况: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?的更多相关文章

  1. UVA 10462 Is There A Second Way Left? 次小生成树

    模板题 #include <iostream> #include <algorithm> #include <cstdio> #include <cstdli ...

  2. UVA 10462 Is There A Second Way Left?(次小生成树&Prim&Kruskal)题解

    思路: Prim: 这道题目中有重边 Prim可以先加一个sec数组来保存重边的次小边,这样不会影响到最小生成树,在算次小生成树时要同时判断次小边(不需判断是否在MST中) Kruskal: Krus ...

  3. 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 ...

  4. UVA 10462 Is There A Second Way Left? (次小生成树+kruskal)

    题目大意: Nasa应邻居们的要求,决定用一个网络把大家链接在一起.给出v个点,e条可行路线,每条路线分别是x连接到y需要花费w. 1:如果不存在最小生成树,输出“No way”. 2:如果不存在次小 ...

  5. UVA - 10462-Is There A Second Way Left? Kruskal求次小生成树

    UVA - 10462 题意: 求次小生成树的模板题,这道题因为有重边的存在,所以用kruskal求比较好. #include <iostream> #include <cstdio ...

  6. [kuangbin带你飞]专题八 生成树 - 次小生成树部分

    百度了好多自学到了次小生成树 理解后其实也很简单 求最小生成树的办法目前遇到了两种 1 prim 记录下两点之间连线中的最长段 F[i][k] 之后枚举两点 若两点之间存在没有在最小生成树中的边 那么 ...

  7. KUANGBIN带你飞

    KUANGBIN带你飞 全专题整理 https://www.cnblogs.com/slzk/articles/7402292.html 专题一 简单搜索 POJ 1321 棋盘问题    //201 ...

  8. kuangbin带你飞 生成树专题 : 次小生成树; 最小树形图;生成树计数

    第一个部分 前4题 次小生成树 算法:首先如果生成了最小生成树,那么这些树上的所有的边都进行标记.标记为树边. 接下来进行枚举,枚举任意一条不在MST上的边,如果加入这条边,那么肯定会在这棵树上形成一 ...

  9. [kuangbin带你飞]专题1-23题目清单总结

    [kuangbin带你飞]专题1-23 专题一 简单搜索 POJ 1321 棋盘问题POJ 2251 Dungeon MasterPOJ 3278 Catch That CowPOJ 3279 Fli ...

随机推荐

  1. linux下用firefox打开csdn故障解决办法

    问题:浏览器打开csdn时博客浏览不全,没有了排版 解决办法: 1.下载一个安装包 命令:epel-release-7-11.noarch.rpm: epel-release-7-11.noarch ...

  2. 电脑莫名重启,VS代码丢失的解决办法

    今天写了一天的代码,然后电脑放在公司了,出去看电影(公司组织红色文化培训..)回来发现电脑重启,再打开电脑,VS的代码都不见了.好慌.... 别慌处理办法来了: 打开everything(没有的可以下 ...

  3. Django学习之视图层

    视图层 小白必会三板斧 HttpResponse render redirect django视图函数必须要给返回一个HttpResponse对象(render和redirect内部返回的也是一个Ht ...

  4. Horizon公司环境

  5. css3动画贝塞尔曲线cubic-bezier,css3动画的五种情况

    当大家开始做css3动画的时候,了解贝塞尔曲线就成了不可或缺的.“贝赛尔曲线”是由法国数学家Pierre Bézier所发明,由此为计算机矢量图形学奠定了基础.它的主要意义在于无论是直线或曲线都能在数 ...

  6. vivado操作基本问题

    1.zynq开发板的构造以及推崇的设计理念 设计推崇的理念是设计有知识产权的可重用的IP模块. 2.操作过程中遇到的问题以及解决方法 (1)综合速度慢解决方案: 我们都知道Vivado编译起来相当的慢 ...

  7. springboot项目实现jar包外配置文件管理

    背景 为实现快速搭建和开发,项目以Springboot框架搭建,springboot搭建的项目可以将项目直接打成jar包并运行,无需自己安装配置Tomcat或者其他服务器,是一种方便快捷的部署方式. ...

  8. Jacoco代码覆盖率工具

    https://www.cnblogs.com/fnng/p/7923314.html https://my.oschina.net/wangmengjun/blog/974067

  9. Monkey命令参数介绍

    1) 参数: -p   参数-p用于约束限制,用此参数指定一个或多个包(Package,即App).指定   包之后,Monkey将只允许系统启动指定的APP.如果不指定包,Monkey将允许系统启动 ...

  10. <HAOI2008>硬币购物

    和神奇dp的战斗 还有容斥原理 终于get到了 #include<cstdio> #include<cstring> #include<iostream> #inc ...