题目:

  曹操在长江上建立了一些点,点之间有一些边连着。如果这些点构成的无向图变成了连通图,那么曹操就无敌了。刘备为了防止曹操变得无敌,就打算去摧毁连接曹操的点的桥。但是诸葛亮把所有炸弹都带走了,只留下一枚给刘备。所以刘备只能炸一条桥。

  题目给出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]的更多相关文章

  1. Hdu 4738【求无向图的桥】.cpp

    题目: 曹操在长江上建立了一些点,点之间有一些边连着.如果这些点构成的无向图变成了连通图,那么曹操就无敌了.刘备为了防止曹操变得无敌,就打算去摧毁连接曹操的点的桥.但是诸葛亮把所有炸弹都带走了,只留下 ...

  2. tarjan算法求无向图的桥、边双连通分量并缩点

    // tarjan算法求无向图的桥.边双连通分量并缩点 #include<iostream> #include<cstdio> #include<cstring> ...

  3. hdu 4738 Caocao's Bridges 求无向图的桥【Tarjan】

    <题目链接> 题目大意: 曹操在长江上建立了一些点,点之间有一些边连着.如果这些点构成的无向图变成了连通图,那么曹操就无敌了.周瑜为了防止曹操变得无敌,就打算去摧毁连接曹操的点的桥.但是诸 ...

  4. I - Caocao's Bridges - hdu 4738(求桥)

    题意:曹操的船之间有一些桥连接,现在周瑜想把这些连接的船分成两部分,不过他只能炸毁一座桥,并且每座桥上有士兵看守,问,他最少需要排多少士兵去炸桥如果不能做到,输出‘-1’ 注意:此题有好几个坑,第一个 ...

  5. hdu 4738 Caocao's Bridges 图--桥的判断模板

    Caocao's Bridges Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  6. hdu 4738 Caocao's Bridges(桥的最小权值+去重)

    http://acm.hdu.edu.cn/showproblem.php?pid=4738 题目大意:曹操有一些岛屿被桥连接,每座都有士兵把守,周瑜想把这些岛屿分成两部分,但他只能炸毁一条桥,问最少 ...

  7. 【求无向图的桥,有重边】ZOJ - 2588 Burning Bridges

    模板题——求割点与桥 题意,要使一个无向图不连通,输出必定要删掉的边的数量及其编号.求桥的裸题,可拿来练手. 套模板的时候注意本题两节点之间可能有多条边,而模板是不判重边的,所以直接套模板的话,会将重 ...

  8. [Tarjan系列] Tarjan算法求无向图的桥和割点

    RobertTarjan真的是一个传说级的大人物. 他发明的LCT,SplayTree这些数据结构真的给我带来了诸多便利,各种动态图论题都可以用LCT解决. 而且,Tarjan并不只发明了LCT,他对 ...

  9. Light OJ - 1026 - Critical Links(图论-Tarjan算法求无向图的桥数) - 带详细注释

     原题链接   无向连通图中,如果删除某边后,图变成不连通,则称该边为桥. 也可以先用Tajan()进行dfs算出所有点 的low和dfn值,并记录dfs过程中每个 点的父节点:然后再把所有点遍历一遍 ...

随机推荐

  1. Spark-PySpark sql各种内置函数

    _functions = { 'lit': 'Creates a :class:`Column` of literal value.', 'col': 'Returns a :class:`Colum ...

  2. Jmeter获取未来时间

    1.添加前置处理器:BeanShell PreProcessor import java.text.SimpleDateFormat; import java.util.Calendar; impor ...

  3. 前端学习框架之layui

    学习地址:https://www.layui.com/demo/laytpl.html

  4. 趣谈linux操作系统笔记-内核初始化

    内核的启动从入口函数 start_kernel() 开始.在 init/main.c 文件中,start_kernel 相当于内核的main 函数.打开这个函数,你会发现,里面是各种各样初始化函数 X ...

  5. 【python3】configparser读取ini配置文件

    在应用过程中,发现下面这个问题: cf=configparser.ConfigParser()读取配置文件时,如果数据包含%这们析特殊符号,就会报出上面的错误,使用cf = configparser. ...

  6. emqttd学习教程(二):emqttd配置说明

    一.配置文件说明emqttd消息服务器通过 etc/ 目录下配置文件进行设置,主要配置文件包括: 配置文件 说明 etc/emq.conf 消息服务器配置文件etc/acl.conf 默认ACL规则配 ...

  7. React之defaultProps、propTypes

    1.新增知识点 /** React中的组件: 解决html 标签构建应用的不足. 使用组件的好处:把公共的功能单独抽离成一个文件作为一个组件,哪里里使用哪里引入. 父子组件:组件的相互调用中,我们把调 ...

  8. nodejs之express中间件cookie-parser使用

    知识点: * .domain的使用,.aaa.com的域名都共享这个cookie信息 * res.cookie(,domain:'.aaa.com'}); * .获取所有cookie,设置cookie ...

  9. JavaScript日常学习5

    JavaScript字符串属性和方法 eg :var txt = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";      var sln = txt.length; ...

  10. Linux环境Nginx安装

    开始前,请确认gcc g++开发类库是否装好,默认已经安装. ububtu平台编译环境可以使用以下指令 apt-get install build-essential apt-get install ...