题目链接: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. python_8(模块)

    第1章 模块 1.1 概述 1.2 模块的分类 1.2.1 内置模块 1.2.2 扩展模块 1.2.3 模块安装 1.2.4 自定义模块第2章 模块之内置模块 2.1 collections模块 2. ...

  2. SOLRJ单机-添加文档,删除,查询操作

    单机solrJ不需要占用太多的服务器和资源,本机使用solr-6.3.0,也不需要配置tomcat. 一.新建一个java工程需要依赖的jar包如下: solr-solrj-6.3.0.jar;  c ...

  3. LINUX 文件夹打包

    tar -zcvf /data/www.tar.gz data/www tar -zcvf 打包后生成的文件名全路径 要打包的目录 压缩: 压缩当前的文件夹 zip -r ./xahot.zip ./ ...

  4. P2142 高精度减法

    题目描述 高精度减法 输入输出格式 输入格式: 两个整数a,b(第二个可能比第一个大) 输出格式: 结果(是负数要输出负号) 输入输出样例 输入样例#1: 2 1 输出样例#1: 1 说明 20%数据 ...

  5. Phalcon初认识

    Phalcon以c扩展交付的全堆栈php开发框架 基本功能 低开销:低内存消耗和CPU相比传统的框架 MVC和HMVC:模块.组件.模型.视图和控制器 依赖注入:依赖注入和位置的服务和它的本身他们的容 ...

  6. (2)Ngixn 编译安装设置开机自启

    设置nginx开机自启 #!/bin/sh # # nginx - this script starts and stops the nginx daemon # # chkconfig: - 85 ...

  7. smile domain name www.bn-nd.com for sell. Please contact boyanzheng at foxmail.com 微笑的域名。请联系邮箱。

  8. ssh 非root用户互信

    之所以要把这个记录下来 是因为它的确和root用户不一样root用户 不需要改动什么权限问题  只要生成私钥/公钥对 即可 但是一样的操作在普通用户上就出了问题了 折腾了老半天 ssh-keygen ...

  9. dnsquery - 使用解析程序查询域名服务器

    SYNOPSIS(总览) dnsquery [-n nameserver ] [-t type ] [-c class ] [-r retry ] [-p period ] [-d ] [-s ] [ ...

  10. CAD交互绘制带周长面积的矩形框(网页版)

    主要用到函数说明: _DMxDrawX::DrawLine 绘制一个直线.详细说明如下: 参数 说明 DOUBLE dX1 直线的开始点x坐标 DOUBLE dY1 直线的开始点y坐标 DOUBLE ...