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过程中每个 点的父节点:然后再把所有点遍历一遍 ...
随机推荐
- 初始化spark
初始化SparkContext 一.初始化sparkimport org.apache.spark.SparkConf;import org.apache.spark.api.java.JavaSpa ...
- Upload-libs通关详解
Uplo ad-labs—详解 1前端验证绕过 前端验证绕过可以直接用burp万能绕过前端JS脚本 方法先上传一张jpg Burp改包然后改后缀 上传成功 2Content-Type方式绕过 此绕过方 ...
- 编程之美-1.1 CPU 曲线
解法二: import time def cpu_curve(): busyTime = 50 # 50 ms的效果比10ms的效果要好 idleTime = busyTime startTime = ...
- ValidateUtil常用验证工具类,如手机、密码、邮箱等
package cn.com.ssk.util.utils; import java.util.regex.Pattern; import org.apache.commons.lang3.Strin ...
- pom.xml报Plugin execution not covered by lifecycle configuration错误
环境 eclipse 4.3.0 maven 3.0.4 m2e 1.4.0 出现场景 以前的老项目,在我的环境(我的环境较新)下,别人老环境不报错. 错误示 ...
- 关于虚拟机中Linux系统无法上网之后的解决方案
我刚刚安装好虚拟机上的Linux的时候,宿主机网络正常,但虚拟机中虽然显示网络连接正常,但无法上网,因此我打开了网络设置 这是默认设置,但上不了网,而按照网上的查找结果,选择NAT是没错的,但仅限于w ...
- leecode 309. 最佳买卖股票时机含冷冻期
/***** //sell[i]表示截至第i天,最后一个操作是卖时的最大收益: //buy[i]表示截至第i天,最后一个操作是买时的最大收益: //cool[i]表示截至第i天,最后一个操作是冷冻期时 ...
- internetwork 与 the Internet的区别
internetwork 表示:互连网络 the Internet 表示:因特网
- Jenkins发布回滚方案
Jenkins回滚可以通过每次发布从主干打tag,然后发布的时候发tag,比如tag, v1, v2,v3 如果我发布了v3,想要回滚回v2,直接在Jenkins中选择v2的tag地址重新构建就可以回 ...
- MySQL 常用工具sysbench/fio/tpcc等测试
为什么要压力测试采购新设备,评估新设备性能开发新项目,评估数据库容量新系统上线前,预估/模拟数据库负载更换数据库版本,评估性能变化 关注指标 CPU %wait,%user,%sys 内存 只内存读 ...