ZOJ2588:Burning Bridges(无向连通图求割边)
题目:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1588
吐下槽,不得不说ZOJ好坑,模版题做了一个多小时。
题意:
* 给出一个无向图,输入n(表示n个定点,1~n), m(m条边,有重边),
* (2 <= N <= 10 000, 1 <= M <= 100 000),求这个无向图中的桥,
* 并输出桥属于输入中边的id.
之前学图的连通性因为没看懂双连通分量,就把连通性的这些知识点搁置了,一直没有刷这方面的题,由于之前已经弄懂求桥的算法,所以看到题就直接上了,结果被一些
小错误给击败了,还好算法的思想没出问题,贴一下代码,以后当模版用。求桥:low[v]>dfn[u](u,v)为树枝边。
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <stack>
#define N 10010
using namespace std;
struct node
{
int x,y,w,next,flag;
} eg[*N];
int tt,head[N],dfn[N],low[N],ti,n,m,top;
int f[*N];
void init()
{
tt=;
ti=;
top=;
memset(head,-,sizeof(head));
memset(dfn,,sizeof(dfn));
memset(f,0,sizeof(f));
}
void add(int xx,int yy,int nu)
{
for(int i=head[xx]; i!=-; i=eg[i].next)//去重
{
if(eg[i].y==yy)
{
eg[i].flag=;
return ;
}
}
eg[tt].x=xx;
eg[tt].y=yy;
eg[tt].w=nu;
eg[tt].flag=;
eg[tt].next=head[xx];
head[xx]=tt++;
}
void tarjan(int u,int fa)
{
dfn[u]=low[u]=ti++;
for(int i=head[u]; i!=-; i=eg[i].next)
{
int v=eg[i].y;
if(v==fa) continue;
if(!dfn[v])
{
tarjan(v,u);
low[u]=min(low[u],low[v]);
if(low[v]>dfn[u]&&!eg[i].flag)
{
f[top++]=eg[i].w;
}
}
else //无向图没有横跨边
{
low[u]=min(dfn[v],low[u]);
}
}
}
int main()
{
int T,xx,yy;
scanf("%d",&T);
while(T--)
{
init();
scanf("%d %d",&n,&m);
for(int i=; i<=m; i++)
{
scanf("%d %d",&xx,&yy);
add(xx,yy,i);
add(yy,xx,i);
}
tarjan(,-);
int sum=;
for(int i=; i<=m; i++)
{
if(f[i])
sum++;
}
printf("%d\n",top);
if(top)
{
sort(f,f+top);
for(int i=; i<top-; i++)
{
printf("%d ",f[i]);
}
printf("%d\n",f[top-]);
}
if(T!=) printf("\n");
}
return ;
}
//无向图是没有横边的
我不知道为什么这么写就PE
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <stack>
#define N 10010
using namespace std;
struct node
{
int x,y,w,next,flag;
}eg[*N];
int tt,head[N],dfn[N],low[N],ti,n,m;
bool f[*N];
void init()
{
tt=;
ti=;
memset(head,-,sizeof(head));
memset(dfn,,sizeof(dfn));
memset(f,false,sizeof(f));
}
void add(int xx,int yy,int nu)
{
for(int i=head[xx];i!=-;i=eg[i].next)
{
if(eg[i].y==yy)
{
eg[i].flag=;
return ;
}
}
eg[tt].x=xx;
eg[tt].y=yy;
eg[tt].w=nu;
eg[tt].flag=;
eg[tt].next=head[xx];
head[xx]=tt++;
}
void tarjan(int u,int fa)
{
dfn[u]=low[u]=ti++;
for(int i=head[u];i!=-;i=eg[i].next)
{
int v=eg[i].y;
if(v==fa) continue;
if(!dfn[v])
{
tarjan(v,u);
low[u]=min(low[u],low[v]);
if(low[v]>dfn[u]&&!eg[i].flag)
{
f[eg[i].w]=true;
}
}
else //无向图没有横跨边
{
low[u]=min(dfn[v],low[u]);
}
}
}
int main()
{
int T,xx,yy;
scanf("%d",&T);
while(T--)
{
init();
scanf("%d %d",&n,&m);
for(int i=;i<=m;i++)
{
scanf("%d %d",&xx,&yy);
add(xx,yy,i);
add(yy,xx,i);
}
tarjan(,-);
int sum=;
for(int i=;i<=m;i++)
{
if(f[i])
sum++;
}
printf("%d\n",sum);
int F=;
for(int i=;i<=m;i++)
{
if(f[i])
{
if(F)
{
printf("%d",i);
F=;
}
else printf(" %d",i);
}
}
printf("\n");
if(T!=) printf("\n");
}
return ;
}
//无向图是没有横边的
ZOJ2588:Burning Bridges(无向连通图求割边)的更多相关文章
- ZOJ 2588 Burning Bridges(无向连通图求割边)
题目地址:ZOJ 2588 由于数组开小了而TLE了..这题就是一个求无向连通图最小割边.仅仅要推断dfn[u]是否<low[v],由于low指的当前所能回到的祖先的最小标号,增加low[v]大 ...
- 无向连通图求割边+缩点+LCA
Network Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 7082 Accepted: 2555 Descripti ...
- 无向连通图求割边(桥)hdu4738,hdu3849
点击打开链接 题目链接: hdu 4738 题目大意: 曹操有N个岛,这些岛用M座桥连接起来 每座桥有士兵把守(也可能没有) 周瑜想让这N个岛不连通,但只能炸掉一座桥 并且炸掉一座桥需要派出不 ...
- ZOJ 2588 Burning Bridges(求含重边的无向连通图的割边) - from lanshui_Yang
Burning Bridges Time Limit: 5 Seconds Memory Limit: 32768 KB Ferry Kingdom is a nice little country ...
- zoj 2588 Burning Bridges【双连通分量求桥输出桥的编号】
Burning Bridges Time Limit: 5 Seconds Memory Limit: 32768 KB Ferry Kingdom is a nice little cou ...
- ZOJ2588 Burning Bridges 无向图的割边
题目大意:求无向图的割边编号. 割边定义:在一个连通图中,如果删去一个边e,图便变成不连通的两个部分,则e为该图的割边. 求法:边(u,v) 不是割边,当且仅当边(u,v)在一个环内.因此所有不在环内 ...
- ZOJ2588 Burning Bridges(割边模板)
题目要输出一个无向图的所有割边.用Tarjan算法: 一遍DFS,构造出一颗深度优先生成树,在原无向图中边分成了两种:树边(生成树上的边)和反祖边(非生成树上的边). 顺便求出每个结点的DFS序dfn ...
- zoj2588 Burning Bridges(无向图的桥)
题目请戳这里 题目大意:给一张无向图,现在要去掉一些边,使图仍然连通,求不能去掉的边. 题目分析:就是求无向图的桥. tarjan算法跑一遍,和无向图割点十分类似,这里要找low[v] > df ...
- 无向连通图求割点(tarjan算法去掉改割点剩下的联通分量数目)
poj2117 Electricity Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 3603 Accepted: 12 ...
随机推荐
- linux ,cron定时任务 备份mysql数据库
cron 定时任务执行备份脚本文件 backup.sh #!/bin/bash USER="root" PASSWORD="xxxxx" DATABASE=&q ...
- linux下mysql 启动命令
1,使用service 启动.关闭MySQL服务 service mysql start service mysql stop service mysql restart 运行上面命令,其实是serv ...
- [转]ASP.NET MVC 5 - 将数据从控制器传递给视图
在我们讨论数据库和数据模型之前,让我们先讨论一下如何将数据从控制器传递给视图.控制器类将响应请求来的URL.控制器类是给您写代码来处理传入请求的地方,并从数据库中检索数据,并最终决定什么类型的返回结果 ...
- swift - UILabel的用法
1.label的声明 class FirstyViewController: UIViewController { var label = UILabel()//初始化 override func v ...
- js 对象引用传值
1)当变量是一个对象(例如:{}或[]),使用 a = b = {} 这种形式传值的话,会变成会用传值,修改 a 时 b 会相应变化,修改 b 时 a 也一样会相应变化 var a = b = {}; ...
- lodash(一)数组
前言: lodash是一个具有一致接口.模块化.高性能等特性的JavaScript工具库(官网地址:http://lodashjs.com/docs/#_differencearray-values) ...
- C++异常 异常机制
C++异常是丢程序运行过程中发生的异常情况(例如被0除)的一种响应.异常提供了将控制权从程序的一个部分传递到另一部分的途径.对异常的处理有3个组成部分:* 引发异常:* 使用处理程序捕获异常:* 使用 ...
- jdbc批处理
批量处理允许将相关的SQL语句分组到批处理中,并通过对数据库的一次调用来提交它们,一次执行完成与数据库之间的交互. 一次向数据库发送多个SQL语句时,可以减少通信开销,从而提高性能. 不需要JDBC驱 ...
- Ubuntu 14.04.02 安装openvswitch-2.3.1
Open vSwitch安装 安装好操作系统 # lsb_release -a LSB Version: core-2.0-amd64:core-2.0-noarch:core-3.0-amd64:c ...
- flag - 待浏览学习网站
学习:gulp+jade(pug)+sass 待浏览网站如下:http://www.ydcss.com/archives/18#lesson1 https://nodejs.org/en/ https ...