题目链接:http://vjudge.net/problem/viewProblem.action?id=14877

题目大意:

要尽可能多的烧毁桥,另外还要保证图的连通性,问哪些桥是绝对不能烧毁的

我们很容易看出不能烧毁的是必然是作为割边存在的桥。

求割边,我们用Tarjan算法,这与求割点有点小区别在与,对于(u,v)的点low[v]>=dfn[u]时就表示u为割点,而low[v]>dfn[u]时才能说明(u,v)是一条割边

因为这里要求出割边的序号,所以在写边的结构体时,用id代表桥的序号,我们每次得到a,b总会添加两条边a->b和b->a,因为这是无向图,所以这两条边公用一个id

另外要注意的是这道题目允许两个地点有多条边出现,所以我们需要用一个tag标志位来注明是否有重边

oid addPath(int a,int b,int c)
{
    int i;
    for(i=first[a];i!=-1;i=path[i].next)
        if(path[i].y==b) break;
    if(i!=-1)//说明是重边
        path[i].tag=1;
    else{
        path[k].y=b,path[k].tag=0,path[k].next=first[a],path[k].id=c;
first[a]=k;
        k++;
    }
}

每次深度搜索一个节点,不断更新上面的low值和dfn值,并找到low[v]>dfn[u]的边并将它们保存到bridge数组中,nbridge用来统计桥的数量

void dfs(int u,int fa)
{
    visit[u]=1,dfn[u]=low[u]=tmpdfn++;
    for(int i=first[u];i!=-1;i=path[i].next){
        int j=path[i].y;

if(!visit[j]){
            dfs(j,u);
            low[u]=min(low[j],low[u]);
            if(low[j]>dfn[u]&&!path[i].tag)
                bridge[++nbridge]=path[i].id;
        }
        else{
            if(j!=fa) low[u]=min(low[u],dfn[j]);//j已被访问且不是父亲节点,说明可以形成一条回边
        }
    }
}

总代码如下:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define N 10005
#define M 100005
int tmpdfn,k,nbridge,bridge[M],visit[N],dfn[N],low[N];
int first[N];
struct Path{
int y,tag,id;
int next;
}path[*M]; void addPath(int a,int b,int c)
{
int i;
for(i=first[a];i!=-;i=path[i].next)
if(path[i].y==b) break;
if(i!=-)//说明是重边
path[i].tag=;
else{
path[k].y=b,path[k].tag=,path[k].next=first[a],path[k].id=c;
first[a]=k;
k++;
}
} void dfs(int u,int fa)
{
visit[u]=,dfn[u]=low[u]=tmpdfn++;
for(int i=first[u];i!=-;i=path[i].next){
int j=path[i].y; if(!visit[j]){
dfs(j,u);
low[u]=min(low[j],low[u]);
if(low[j]>dfn[u]&&!path[i].tag)
bridge[++nbridge]=path[i].id;
}
else{
if(j!=fa) low[u]=min(low[u],dfn[j]);//j已被访问且不是父亲节点,说明可以形成一条回边
}
}
}
int main()
{
int T,n,m,x,y;
scanf("%d",&T); while(T--){
scanf("%d%d",&n,&m);
k=,nbridge=,tmpdfn=;
memset(first,-,sizeof(first));
memset(visit,,sizeof(visit));
memset(bridge,,sizeof(bridge));
for(int i=;i<=m;i++)
{
scanf("%d%d",&x,&y);
addPath(x,y,i);
addPath(y,x,i);
}
dfs(,);
printf("%d\n",nbridge);
sort(bridge+,bridge+nbridge+);
for(int i=;i<nbridge;i++) printf("%d ",bridge[i]);
if(nbridge>) printf("%d\n",bridge[nbridge]);
if(T>) printf("\n");
}
return ;
}

ZOJ 2588 求割边问题的更多相关文章

  1. ZOJ 2588 Burning Bridges(无向连通图求割边)

    题目地址:ZOJ 2588 由于数组开小了而TLE了..这题就是一个求无向连通图最小割边.仅仅要推断dfn[u]是否<low[v],由于low指的当前所能回到的祖先的最小标号,增加low[v]大 ...

  2. ZOJ Problem - 2588 Burning Bridges tarjan算法求割边

    题意:求无向图的割边. 思路:tarjan算法求割边,访问到一个点,如果这个点的low值比它的dfn值大,它就是割边,直接ans++(之所以可以直接ans++,是因为他与割点不同,每条边只访问了一遍) ...

  3. ZOJ 2588 Burning Bridges (tarjan求割边)

    题目链接 题意 : N个点M条边,允许有重边,让你求出割边的数目以及每条割边的编号(编号是输入顺序从1到M). 思路 :tarjan求割边,对于除重边以为中生成树的边(u,v),若满足dfn[u] & ...

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

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

  5. [学习笔记]tarjan求割边

    上午打模拟赛的时候想出了第三题题解,可是我不会求割边只能暴力判割边了QAQ 所以,本文介绍求割边(又称桥). 的定义同求有向图强连通分量. 枚举当前点的所有邻接点: 1.如果某个邻接点未被访问过,则访 ...

  6. 【NOIP训练】【Tarjan求割边】上学

    题目描述 给你一张图,询问当删去某一条边时,起点到终点最短路是否改变. 输入格式 第一行输入两个正整数,分别表示点数和边数.第二行输入两个正整数,起点标号为,终点标号为.接下来行,每行三个整数,表示有 ...

  7. HDU 4738——Caocao's Bridges——————【求割边/桥的最小权值】

     Caocao's Bridges Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u S ...

  8. POJ3694(求割边)

    Network Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 7943   Accepted: 2893 Descripti ...

  9. tarjan求割边割点

    tarjan求割边割点 内容及代码来自http://m.blog.csdn.net/article/details?id=51984469 割边:在连通图中,删除了连通图的某条边后,图不再连通.这样的 ...

随机推荐

  1. 1051 - Good or Bad DFS 记忆化搜索

    http://lightoj.com/volume_showproblem.php?problem=1051 对于每个位置,设dfs(cur, one, two)表示前i个字母,拥有辅音字母one个, ...

  2. MySQLDump在使用之前一定要想到的事情 [转载]

    转载于:http://blog.itpub.net/29254281/viewspace-1392757/ MySQLDump经常用于迁移数据和备份. 下面创建实验数据,两个数据库和若干表create ...

  3. ASP.NET相关事件及JS的执行顺序

    实验代码: ASPX: <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="We ...

  4. 关于HashMap中hash()函数的思考

    关于HashMap中hash()函数的思考 JDK7中hash函数的实现   static int hash(int h) { h ^= (h >>> 20) ^ (h >&g ...

  5. 第3章 接口与API设计 52条笔记

    第3章 接口与API设计 52条笔记 第15条: 用前缀避免命名空间冲突 Objective-C 没有其他语言那种内置的命名空间机制 .鉴于此,我们在起名时要设法避免潜在的命名冲突,否则很容易就重名了 ...

  6. 【HEVC帧间预测论文】P1.4 Motion Vectors Merging: Low Complexity Prediction Unit Decision

    Motion Vectors Merging: Low Complexity Prediction Unit Decision Heuristic for the inter-Prediction o ...

  7. hdu 3232 Crossing Rivers 过河(数学期望)

    题意:你在点A,目的地是点B,A和B的距离为D.中间隔了好多条河(所有河不会重叠),每条河有3个参数(P,L,V),其中P表示距离A点的长度,L表示河的长度,V表示河里的船的速度.假设每条河中仅有1条 ...

  8. varchar2(100 char)是什么意思

    最佳答案   varchar2(100 char)最长可以插入100个任意字符而varchar2(100)最长可以插入100个英文字符

  9. TensorFlow中屏蔽warning的方法

    问题 使用sudo pip3 install tensorflow安装完CPU版tensorflow后,运行简单的测试程序,出现如下警告: I tensorflow/core/platform/cpu ...

  10. SQA定义、质量模型、SQA与测试的关系