题目就是求一副图的割边,然后对于那些有重复的边的,不能算做割边。

思路就是每次加入一条边的时候,判断这条边是否存在过,存在过的话,就把那条边设为inf,表示不能作为割边。于是有了这样的代码

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL; #include <iostream>
#include <sstream>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string> const int maxn=+;
struct data {
int u,v,id;
int next;
} e[maxn*];
int first[+];
int num;//??????
bool isok (int u,int v) {
//???u????????????
for (int i=first[u]; i; i=e[i].next) {
if (e[i].v==v) {
e[i].id=inf;
return false;
}
}
return true;
}
void add (int u,int v,int id) {
if (!isok(u,v)) return ;//???????????????
++num;
e[num].u=u;
e[num].v=v;
e[num].id=id;
e[num].next=first[u];
first[u]=num;
return ;
}
int DFN[+];//???????
int low[+];//????????
int when;//?????????
int root;
set<int>pr;
void dfs (int cur,int father) {
++when;
DFN[cur]=when;
low[cur]=when;
for (int i=first[cur]; i; i=e[i].next) {
int v=e[i].v;//cur????v???
if (!DFN[v]) { //??????
dfs(v,cur);
low[cur]=min(low[cur],low[v]);
if (low[v]>DFN[cur]&&e[i].id!=inf) {
pr.insert(e[i].id);
}
} else if(v!=father) {
low[cur]=min(low[cur],DFN[v]);
}
}
return ;
}
void init () {
pr.clear();
memset(DFN,,sizeof(DFN));
memset(low,,sizeof(low));
memset (first,,sizeof first);
when=;
num=;
return ;
}
int n,m;
void work () {
init ();
for (int i=; i<=m; i++) {
int u,v;
scanf ("%d%d",&u,&v);
add(u,v,i);
add(v,u,i);
}
root=;//????
dfs(,root);
printf ("%d\n",pr.size());
for (set<int>::iterator it= pr.begin(); it!=pr.end(); ++it) {
printf ("%d ",*it);
}
printf ("\n");
return ;
}
int main () {
while (scanf ("%d%d",&n,&m)!=EOF) work ();
return ;
}

240ms过的。但是应该会有些坑爹的图,卡到它TLE的。

所以这个方法不行

考虑去重,做到O(m)

用used[v] = u表示u--v这样有一条边了。

建立完整张图后,遍历一次,如果重复的话,就去掉就行了。used数组不用清空,因为值u肯定是不同的。

坑就是出现了两次,才能判断第二条边重复了。那么第一条边怎么设置为inf呢?

方法就是用一个数组togo[v] = j表示,当前顶点v的上一条边是j。去重即可。

压缩时间为44ms

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL; #include <iostream>
#include <sstream>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string> const int maxn=+;
struct data {
int u,v,id;
int next;
} e[maxn*];
int first[+];
int num;//用到第几条边
bool isok (int u,int v) {
//问一下u顶点所有边能不能去这个点
for (int i=first[u]; i; i=e[i].next) {
if (e[i].v==v) {
e[i].id=inf;
return false;
}
}
return true;
}
void add (int u,int v,int id) {
// if (!isok(u,v)) return ;//判断是否有重复的边,绝对不是桥
++num;
e[num].u=u;
e[num].v=v;
e[num].id=id;
e[num].next=first[u];
first[u]=num;
return ;
}
int DFN[+];//第几个被访问到
int low[+];//最厉害能访问到谁
int used[ + ];
int togo[ + ];
int when;//什么时候被访问到的
int root;
set<int>pr;
void dfs (int cur,int father) {
++when;
DFN[cur]=when;
low[cur]=when;
for (int i=first[cur]; i; i=e[i].next) {
int v=e[i].v;//cur是爸爸,v是儿子
if (!DFN[v]) { //没访问过的话
dfs(v,cur);
low[cur]=min(low[cur],low[v]);
if (low[v]>DFN[cur]&&e[i].id!=inf) {
pr.insert(e[i].id);
}
} else if(v!=father) {
low[cur]=min(low[cur],DFN[v]);
}
}
return ;
}
void init () {
memset(togo, , sizeof togo);
memset(used, , sizeof used);
pr.clear();
memset(DFN,,sizeof(DFN));
memset(low,,sizeof(low));
memset (first,,sizeof first);
when=;
num=;
return ;
}
int n,m;
void work () {
init ();
for (int i=; i<=m; i++) {
int u,v;
scanf ("%d%d",&u,&v);
add(u,v,i);
add(v,u,i);
}
for (int i = ; i <= n; ++i) {
// memset(used, 0, sizeof used);
for (int j = first[i]; j; j = e[j].next) {
if (used[e[j].v] == e[j].u) {
e[j].id = inf;
e[togo[e[j].v]].id = inf;
}
used[e[j].v] = e[j].u;
togo[e[j].v] = j;
}
}
root=;//从根节点
dfs(,root);
printf ("%d\n",pr.size());
for (set<int>::iterator it= pr.begin(); it!=pr.end(); ++it) {
printf ("%d ",*it);
}
printf ("\n");
return ;
}
int main () {
#ifdef local
freopen("data.txt", "r", stdin);
#endif
while (scanf ("%d%d",&n,&m)!=EOF) work ();
return ;
}

ACdream 1236 Burning Bridges 割边 + 去重边的更多相关文章

  1. ZOJ 2588 Burning Bridges 割边(处理重边)

    <题目链接> 题目大意: 给定一个无向图,让你尽可能的删边,但是删边之后,仍然需要保证图的连通性,输出那些不能被删除的边. 解题分析: 就是无向图求桥的题目,主要是提高一下处理重边的姿势. ...

  2. zoj 2588 Burning Bridges(割边/桥)

    题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1588 题意:Ferry王国有n个岛,m座桥,每个岛都可以互达,现在要 ...

  3. ZOJ 2588 Burning Bridges(求含重边的无向连通图的割边) - from lanshui_Yang

    Burning Bridges Time Limit: 5 Seconds Memory Limit: 32768 KB Ferry Kingdom is a nice little country ...

  4. Burning Bridges 求tarjan求割边

    Burning Bridges 给出含有n个顶点和m条边的连通无向图,求出所有割边的序号. 1 #include <cstdio> 2 #include <cstring> 3 ...

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

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

  6. zoj——2588 Burning Bridges

    Burning Bridges Time Limit: 5 Seconds      Memory Limit: 32768 KB Ferry Kingdom is a nice little cou ...

  7. zoj 2588 Burning Bridges【双连通分量求桥输出桥的编号】

    Burning Bridges Time Limit: 5 Seconds      Memory Limit: 32768 KB Ferry Kingdom is a nice little cou ...

  8. xtu summer individual 5 E - Burning Bridges

    Burning Bridges Time Limit: 5000ms Memory Limit: 32768KB This problem will be judged on ZJU. Origina ...

  9. ZOJ 2588 Burning Bridges(求桥的数量,邻接表)

    题目地址:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2588 Burning Bridges Time Limit: 5 ...

随机推荐

  1. bzoj 1023 [SHOI2008]cactus仙人掌图 ( poj 3567 Cactus Reloaded )——仙人掌直径模板

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1023 http://poj.org/problem?id=3567 因为lyd在讲课,所以有 ...

  2. Python:删除字符串中的字符

    一.删除字符串两端的一种或多种字符 #strip().lstrip().rstrip()方法:(默认删除空格符) A.list.strip(字符):删除字符串两端的一种或多种字符: #例:删除字符串s ...

  3. windows7下安装gem包---bcrypt-ruby

    在Gemfile中添加 gem 'bcrypt-ruby', '~> 3.0.0' 然后执行bundle install,rails服务启动没有问题,但是运行程序时页面报错如下: cannot ...

  4. Mac 远程连接Linux服务器及上传、下载命令

    1.使用ssh命令连接远程服务器主机 1.不设置端口,默认就是22 ssh root@192.168.18.129 1.1.设置端口例: ssh -p 22 root@192.168.18.1292. ...

  5. 关于redis,学会这8点就够了(转)

    1.redis是什么 redis是一种支持Key-Value等多种数据结构的存储系统.可用于缓存.事件发布或订阅.高速队列等场景.该数据库使用ANSI C语言编写,支持网络,提供字符串.哈希.列表.队 ...

  6. javadoc 工具生成开发API文档

    =====================先来一点成就感===================== package com.springMybatis.dao; import com.springMy ...

  7. USB插拔检测程序

    一.手动添加ON_WM_DEVICECHANGE()消息 二.添加头文件#include <Dbt.h> 三.定义设备的GUID static const GUID GUID_DEVINT ...

  8. HTML5 中文乱码

    <meta charste="utf-8"> 只是告诉浏览器要用utf-8来解释,而文档的编码,是在你保存时的选择决定的.如果保存ANSI 然后用utf-8解释,肯定是 ...

  9. tar压缩解压缩

    Linux下的tar压缩解压缩命令详解tar -c: 建立压缩档案-x:解压-t:查看内容-r:向压缩归档文件末尾追加文件-u:更新原压缩包中的文件 这五个是独立的命令,压缩解压都要用到其中一个,可以 ...

  10. Lua中的点、冒号与self

    Lua中的点.冒号与self,它们之间的关系主要体现在函数的定义与调用上,Lua在函数定义时可以用点也可以用冒号,如: function mytable.fun(p) return p end fun ...