Hdu 4738【tanjan求无向图的桥】割边判定定理 dfn[x] < low[y]
题目:
曹操在长江上建立了一些点,点之间有一些边连着。如果这些点构成的无向图变成了连通图,那么曹操就无敌了。刘备为了防止曹操变得无敌,就打算去摧毁连接曹操的点的桥。但是诸葛亮把所有炸弹都带走了,只留下一枚给刘备。所以刘备只能炸一条桥。
题目给出n,m。表示有n个点,m条桥。
接下来的m行每行给出a,b,c,表示a点和b点之间有一条桥,而且曹操派了c个人去守卫这条桥。
现在问刘备最少派多少人去炸桥。
如果无法使曹操的点成为多个连通图,则输出-1.
思路:
就是用tarjan算法算出桥的数量,再比较哪一个的值最小。
Tips:
注意三点:
①. 有重边,所以tarjan算法要处理重边。有两种处理方法,一种是先把所有的边存下,发现两点有重边的时候就只给这两个点连一条权值为无穷大的边。或者是在tarjan算法里处理重边,即使之求u或u的子树能够追溯到的最早的栈中节点的次序号时可访问父节点的次序号。
②. 如果无向图图本身已经有两个连通图了,就无需派人去炸桥,这时候输出0。
③. 如果求出来的最小权值桥的守卫人数为0时,也需要派出一个人去炸桥。
Code:
// tarjan算法求无向图的桥、边双连通分量并缩点
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include <bits/stdc++.h>
#define cls(s,h) memset(s,h,sizeof s)
using namespace std;
const int N = ;
int n, m ;
struct edge
{
int to;
int pre;
int id;
int w;
};
edge E[N*N];
int head[N],tot;
//int soldier[N][N];//第一种方法所需的的邻接矩阵
int low[N],dfn[N],ts,top,st[N],ins[N];
int minn; void init()
{
cls(head,-);
tot=;
//CLR(soldier,INF);
cls(low,);
cls(dfn,);
ts=top=;
cls(ins,);
minn=1e8;
}
inline void add(int s,int t,int w,int id)
{
E[tot].to=t;
E[tot].id=id;
E[tot].w=w;
E[tot].pre=head[s];
head[s]=tot++;
}
void tarjan(int u,int id)
{
low[u]=dfn[u]=++ts;
ins[u]=;
st[top++]=u;
int v;
for (int i=head[u]; ~i; i=E[i].pre)
{
v=E[i].to;
if(id==E[i].id)
continue;
if(!dfn[v])
{
tarjan(v,E[i].id);
low[u]=min<int>(low[v],low[u]);
if(low[v]>dfn[u])
{
int need=E[i].w;
if(need<minn)
minn=need;
}
}
else if(ins[v])
low[u]=min<int>(low[u],dfn[v]);
}
if(low[u]==dfn[u])
{
do
{
v=st[--top];
ins[v]=;
}
while (u!=v);
}
} int main()
{
while(scanf("%d%d",&n,&m)&&n+m)
{
init(); //tot = 1;
for (int i = ; i <= m; i++)
{
int x, y,z;
scanf("%d%d%d", &x, &y,&z);
add(x, y,z,i), add(y,x,z,i);
}
int k = ;
minn = 1e8;
for (int i = ; i <= n; i++)
if (!dfn[i]) tarjan(i, -),k++;
//for (int i = 2; i < tot; i += 2)
// if (bridge[i])
// printf("%d %d\n", ver[i ^ 1], ver[i]); // for (int i = 1; i <= n; i++)
// if (!c[i]) {
// ++dcc;
// dfs(i);
// }
//printf("There are %d e-DCCs.\n", dcc);
//for (int i = 1; i <= n; i++)
// printf("%d belongs to DCC %d.\n", i, c[i]); //for (int i = 2; i <= tot; i++) {
// int x = ver[i ^ 1], y = ver[i];
// if (c[x] == c[y]) continue;
// add_c(c[x], c[y]);
// }
//printf("缩点之后的森林,点数 %d,边数 %d\n", dcc, tc / 2); //for (int i = 2; i < tc; i += 2)
//printf("%d %d %d\n", vc[i ^ 1], vc[i],edge[i]);
// minn = min(minn,edge[i]);
if(k > )
minn = ;
else if(minn == )
minn = ;
else if(minn == 1e8)
minn = -;
printf("%d\n",minn); }
return ;
}
// tarjan算法求无向图的桥、边双连通分量并缩点
// 割边判定定理 dfn[x] < low[y]
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include <bits/stdc++.h>
#define cls(s,h) memset(s,h,sizeof s)
using namespace std;
const int N = ;
int n, m ;
struct edge
{
int to;
int pre;
int id;
int w;
};
edge E[N*N];
int head[N],tot;
//int soldier[N][N];//第一种方法所需的的邻接矩阵
int low[N],dfn[N],ts,top,st[N],ins[N];
int minn; void init()
{
cls(head,-);
tot=;
//CLR(soldier,INF);
cls(low,);
cls(dfn,);
ts=top=;
cls(ins,);
minn=1e8;
}
inline void add(int s,int t,int w,int id)
{
E[tot].to=t;
E[tot].id=id;
E[tot].w=w;
E[tot].pre=head[s];
head[s]=tot++;
}
void tarjan(int u,int id)
{
low[u]=dfn[u]=++ts;
ins[u]=;
st[top++]=u;
int v;
for (int i=head[u]; ~i; i=E[i].pre)
{
v=E[i].to;
if(id==E[i].id)
continue;
if(!dfn[v])
{
tarjan(v,E[i].id);
low[u]=min<int>(low[v],low[u]);
if(low[v]>dfn[u])
{
//枚举每一个桥,找到最小的桥
int need=E[i].w;
if(need<minn)
minn=need; }
}
else if(ins[v])
low[u]=min<int>(low[u],dfn[v]);
}
if(low[u]==dfn[u])
{
do
{
v=st[--top];
ins[v]=;
}
while (u!=v);
}
} int main()
{
while(scanf("%d%d",&n,&m)&&n+m)
{
init(); //tot = 1;
for (int i = ; i <= m; i++)
{
int x, y,z;
scanf("%d%d%d", &x, &y,&z);
add(x, y,z,i), add(y,x,z,i);
}
int k = ;
minn = 1e8;
for (int i = ; i <= n; i++)
if (!dfn[i]) tarjan(i, -),k++;//连通块数量
if(k > )
minn = ;
else if(minn == )
minn = ;
else if(minn == 1e8)
minn = -;
printf("%d\n",minn); }
return ;
}
更新代码
Hdu 4738【tanjan求无向图的桥】割边判定定理 dfn[x] < low[y]的更多相关文章
- Hdu 4738【求无向图的桥】.cpp
题目: 曹操在长江上建立了一些点,点之间有一些边连着.如果这些点构成的无向图变成了连通图,那么曹操就无敌了.刘备为了防止曹操变得无敌,就打算去摧毁连接曹操的点的桥.但是诸葛亮把所有炸弹都带走了,只留下 ...
- tarjan算法求无向图的桥、边双连通分量并缩点
// tarjan算法求无向图的桥.边双连通分量并缩点 #include<iostream> #include<cstdio> #include<cstring> ...
- hdu 4738 Caocao's Bridges 求无向图的桥【Tarjan】
<题目链接> 题目大意: 曹操在长江上建立了一些点,点之间有一些边连着.如果这些点构成的无向图变成了连通图,那么曹操就无敌了.周瑜为了防止曹操变得无敌,就打算去摧毁连接曹操的点的桥.但是诸 ...
- I - Caocao's Bridges - hdu 4738(求桥)
题意:曹操的船之间有一些桥连接,现在周瑜想把这些连接的船分成两部分,不过他只能炸毁一座桥,并且每座桥上有士兵看守,问,他最少需要排多少士兵去炸桥如果不能做到,输出‘-1’ 注意:此题有好几个坑,第一个 ...
- hdu 4738 Caocao's Bridges 图--桥的判断模板
Caocao's Bridges Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- hdu 4738 Caocao's Bridges(桥的最小权值+去重)
http://acm.hdu.edu.cn/showproblem.php?pid=4738 题目大意:曹操有一些岛屿被桥连接,每座都有士兵把守,周瑜想把这些岛屿分成两部分,但他只能炸毁一条桥,问最少 ...
- 【求无向图的桥,有重边】ZOJ - 2588 Burning Bridges
模板题——求割点与桥 题意,要使一个无向图不连通,输出必定要删掉的边的数量及其编号.求桥的裸题,可拿来练手. 套模板的时候注意本题两节点之间可能有多条边,而模板是不判重边的,所以直接套模板的话,会将重 ...
- [Tarjan系列] Tarjan算法求无向图的桥和割点
RobertTarjan真的是一个传说级的大人物. 他发明的LCT,SplayTree这些数据结构真的给我带来了诸多便利,各种动态图论题都可以用LCT解决. 而且,Tarjan并不只发明了LCT,他对 ...
- Light OJ - 1026 - Critical Links(图论-Tarjan算法求无向图的桥数) - 带详细注释
原题链接 无向连通图中,如果删除某边后,图变成不连通,则称该边为桥. 也可以先用Tajan()进行dfs算出所有点 的low和dfn值,并记录dfs过程中每个 点的父节点:然后再把所有点遍历一遍 ...
随机推荐
- Redis的一点笔记
Redis 是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库. Redis 优势: 性能极高 – Redis能读的速度是110000次/s,写的速度是81000次/s . 丰富 ...
- IDEA的Python工程在inspections时提示:The JDK is not configured properly for this project. Inspection cannot proceed.
原因:IDEA将工程误认为了Java工程. 解决方法:如果确认这是个Python工程,修改*.iml文件,将下面的这一行删除 <orderEntry type="inheritedJd ...
- Authing新功能——小程序扫码登录
近期,Authing 发布了新功能--小程序扫码登录. 小程序扫码登录指使用Authing小程序身份管家在网页端或其它客户端执行微信登录,目前的SDK仅支持客户端JavaScript.其它语言若想使用 ...
- MySQL 获取格林时间
SELECT *FROM 表面WHERE DATE_SUB( NOW( ), INTERVAL 3 MINUTE ) <= CONVERT_TZ( 时间字段, @@SESSION.time_zo ...
- 实现真正意义上的前后端分离------由淘宝引入nodejs引发的思考
说起前后端分离,大家包括我自己都会想到: 当今流行的MVC不就是最标准的前后端分离吗? 说到这里,我不禁要反问,MVC真正的实现了前后端分离了吗? 无论是PHP的MVC框架TP还是JAVA的MVC框架 ...
- SSH上传文件出现error
如上图,因为我在SSH上的用户没有对Linux服务器的文件夹的修改权限,我在linux上把文件夹的权限改为可读可改,就可以了
- 五、smarty模板继承特性
1.如何去实现模板之间的继承 继承是发生在模板之间的事,和PHP程序没有关系的 方法一: 在模板中使用<{extends}>函数实现模板的继承 <{extends file=”模板文 ...
- vscode 配置go环境 可调试
1.go下载安装并配置环境变量 2.安装工具: 1)安装gocode go get -u -v github.com/nsf/gocode 2)安装godef go get -u -v githu ...
- accesstoken 中控服务器 并发刷新 加并发锁
https://www.cnblogs.com/digdeep/p/4369725.html 由获取微信access_token引出的Java多线程并发问题 https://mp.weixin.qq. ...
- php实现:当未登录时转到登陆页面
判断session是否存在,不存在则跳转到登录页面session_start(); if ( !$_SESSION['xxx'] ) { header("Location: login ...