ZOJ 2588 求割边问题
题目链接: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 求割边问题的更多相关文章
- ZOJ 2588 Burning Bridges(无向连通图求割边)
题目地址:ZOJ 2588 由于数组开小了而TLE了..这题就是一个求无向连通图最小割边.仅仅要推断dfn[u]是否<low[v],由于low指的当前所能回到的祖先的最小标号,增加low[v]大 ...
- ZOJ Problem - 2588 Burning Bridges tarjan算法求割边
题意:求无向图的割边. 思路:tarjan算法求割边,访问到一个点,如果这个点的low值比它的dfn值大,它就是割边,直接ans++(之所以可以直接ans++,是因为他与割点不同,每条边只访问了一遍) ...
- ZOJ 2588 Burning Bridges (tarjan求割边)
题目链接 题意 : N个点M条边,允许有重边,让你求出割边的数目以及每条割边的编号(编号是输入顺序从1到M). 思路 :tarjan求割边,对于除重边以为中生成树的边(u,v),若满足dfn[u] & ...
- 【求无向图的桥,有重边】ZOJ - 2588 Burning Bridges
模板题——求割点与桥 题意,要使一个无向图不连通,输出必定要删掉的边的数量及其编号.求桥的裸题,可拿来练手. 套模板的时候注意本题两节点之间可能有多条边,而模板是不判重边的,所以直接套模板的话,会将重 ...
- [学习笔记]tarjan求割边
上午打模拟赛的时候想出了第三题题解,可是我不会求割边只能暴力判割边了QAQ 所以,本文介绍求割边(又称桥). 的定义同求有向图强连通分量. 枚举当前点的所有邻接点: 1.如果某个邻接点未被访问过,则访 ...
- 【NOIP训练】【Tarjan求割边】上学
题目描述 给你一张图,询问当删去某一条边时,起点到终点最短路是否改变. 输入格式 第一行输入两个正整数,分别表示点数和边数.第二行输入两个正整数,起点标号为,终点标号为.接下来行,每行三个整数,表示有 ...
- HDU 4738——Caocao's Bridges——————【求割边/桥的最小权值】
Caocao's Bridges Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u S ...
- POJ3694(求割边)
Network Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 7943 Accepted: 2893 Descripti ...
- tarjan求割边割点
tarjan求割边割点 内容及代码来自http://m.blog.csdn.net/article/details?id=51984469 割边:在连通图中,删除了连通图的某条边后,图不再连通.这样的 ...
随机推荐
- Problem E: 穷游中国在统题 优先队列 + 模拟
http://www.gdutcode.sinaapp.com/problem.php?cid=1049&pid=4 Problem E: 穷游中国在统题 Description Travel ...
- ES相关概念理解
Elasticsearch特点:分布式,高性能,高可用,高伸缩的搜索和分析: 1)可作为一个大型分布式集群,处理PB级别的数据,服务大型公司,亦可运行在少数或单台设备上服务小型公司 分布式的特性: E ...
- 页面html图片按钮多种写法
原地址:http://blog.163.com/weison_hi/blog/static/17680404720118534033788/ 第一种: 在一般情况下按钮提交表单: <form i ...
- spring boot 的redis 之初理解
项目到末尾了快, 这几天安排我结合业务场景给项目加上redis 缓存, 我接到这个任务也是懵逼了一会儿: 问了一句让我自己先想办法,没办法硬着头皮查吧, 要不不得不说spring boot 还是好用, ...
- Mysql框架---HMySql
Java 数据库框架 在我学习java数据库框架的时候,第一个用的是Hibernate,但是到现在,我可能已经快忘记它了,毕竟快两年没有碰的东西,后来一直再用MyBatis.因为它简单. 但是本文不会 ...
- Java&Xml教程(十)XML作为属性文件使用
我们通常会将Java应用的配置参数保存在属性文件中,Java应用的属性文件可以是一个正常的基于key-value对,以properties为扩展名的文件,也可以是XML文件. 在本案例中,將会向大家介 ...
- php 缓存工具类 实现网页缓存
php 缓存工具类 实现网页缓存 php程序在抵抗大流量访问的时候动态网站往往都是难以招架,所以要引入缓存机制,一般情况下有两种类型缓存 一.文件缓存 二.数据查询结果缓存,使用内存来实现高速缓存 本 ...
- Sublime折腾记录
本文可以理解为FAQ,主要是为了大家GET一些技能,具体内容包括LICENSE.重置.Package Control的安装,其他内容以后可能补充... 最后说明一下自己的版本:Build 3114 L ...
- COGS 1439. [NOIP2013]货车运输
★★☆ 输入文件:truck.in 输出文件:truck.out 简单对比时间限制:1 s 内存限制:128 MB [题目描述] [来源] CCF全国信息学奥林匹克联赛(NOIP201 ...
- SQLite - SELECT查询
SQLite - SELECT查询 SQLite SELECT语句用于获取数据从一个SQLite数据库表返回数据结果表的形式.也称为result-sets这些结果表. 语法 SQLite SELECT ...