题目链接: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. CentOS Linux下MySQL 5.1.x的安装、优化和安全配置

    下载页面:http://dev.mysql.com/downloads/mysql/5.1.html#downloads 到页面底部,找到Source downloads,这个是源码版本,下载第1个T ...

  2. AJPFX总结Collection集合(下)

    List集合特有方法 特有方法.凡是可以操作角标的方法都是该体系特有的方法. 增          add(index,element);在指定位置添加元素          addAll(index ...

  3. [转]彻底明确怎样设置minSdkVersion和targetSdkVersion

    minSdkVersion和targetSdkVersion相信非常多人都不太理解.我在网上也看了很多关于这两者差别的文章,感觉说的都非常模糊.直到我在stackOverFlow看到Android M ...

  4. CF778B(round 402 div.2 E) Bitwise Formula

    题意: Bob recently read about bitwise operations used in computers: AND, OR and XOR. He have studied t ...

  5. 微信小程序 可用性一览

    1. 调试vConsole微信小程序通过vConsole的形式观察控制台打印.打印到vConsole控制台的是由 JSON 转化的字符串.这还是可以起到调试作用的. Source Map当es6 转  ...

  6. MATLAB学习总结(1)

    MATLAB学习总结(1)   path help path cd(current directory) savepath pathtool

  7. 我所理解的MVVM

    将UI中的数据适配.交互处理: controller中与UI密切相关的功能: 剥离出来,形成单独的模块: 以增加UI和Controller的灵活性.

  8. 油猴和EX-百度脚本 百度网盘下载

    pansoso.com 搜网盘 油猴和EX-百度脚本.zip https://aleikeji.pipipan.com/fs/845023-331102839

  9. c++如何使用全局变量

    在xxxx.h文件中使用extern声明变量: extern int i; 在xxxx.cpp文件中定义变量: int i; 声明和定义都只需一次.

  10. 搜索 || DFS || UOJ 146 信息传递

    DFS+回溯 找最小环 每个人知道自己的生日,每次把自己知道的生日告诉固定的一个人,问最少多少次之后能从别人口中听到自己的生日 找一个最小环 #include <iostream> #in ...