ACdream 1236 Burning Bridges 割边 + 去重边
题目就是求一副图的割边,然后对于那些有重复的边的,不能算做割边。
思路就是每次加入一条边的时候,判断这条边是否存在过,存在过的话,就把那条边设为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 割边 + 去重边的更多相关文章
- ZOJ 2588 Burning Bridges 割边(处理重边)
<题目链接> 题目大意: 给定一个无向图,让你尽可能的删边,但是删边之后,仍然需要保证图的连通性,输出那些不能被删除的边. 解题分析: 就是无向图求桥的题目,主要是提高一下处理重边的姿势. ...
- zoj 2588 Burning Bridges(割边/桥)
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1588 题意:Ferry王国有n个岛,m座桥,每个岛都可以互达,现在要 ...
- ZOJ 2588 Burning Bridges(求含重边的无向连通图的割边) - from lanshui_Yang
Burning Bridges Time Limit: 5 Seconds Memory Limit: 32768 KB Ferry Kingdom is a nice little country ...
- Burning Bridges 求tarjan求割边
Burning Bridges 给出含有n个顶点和m条边的连通无向图,求出所有割边的序号. 1 #include <cstdio> 2 #include <cstring> 3 ...
- ZOJ 2588 Burning Bridges(无向连通图求割边)
题目地址:ZOJ 2588 由于数组开小了而TLE了..这题就是一个求无向连通图最小割边.仅仅要推断dfn[u]是否<low[v],由于low指的当前所能回到的祖先的最小标号,增加low[v]大 ...
- zoj——2588 Burning Bridges
Burning Bridges Time Limit: 5 Seconds Memory Limit: 32768 KB Ferry Kingdom is a nice little cou ...
- zoj 2588 Burning Bridges【双连通分量求桥输出桥的编号】
Burning Bridges Time Limit: 5 Seconds Memory Limit: 32768 KB Ferry Kingdom is a nice little cou ...
- xtu summer individual 5 E - Burning Bridges
Burning Bridges Time Limit: 5000ms Memory Limit: 32768KB This problem will be judged on ZJU. Origina ...
- ZOJ 2588 Burning Bridges(求桥的数量,邻接表)
题目地址:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2588 Burning Bridges Time Limit: 5 ...
随机推荐
- 【转】Pro Android学习笔记(十五):用户界面和控制(3):Button控件
目录(?)[-] 基础Button ImageButton ToggleButton CheckBox RadioButton 基础Button Button是最常用的基础控件之一,在Android中 ...
- 查看,上传crushmap命令
标签(空格分隔): ceph,ceph运维,crushmap 查看crushmap命令 从mon节点获取crushmap: # ceph osd getcrushmap -o crush.map 反编 ...
- Mybatis连接mysql数据库出现乱码
对于mysql数据库的乱码问题,有两中情况: 1. mysql数据库编码问题(建库时设定). 2. 连接mysql数据库的url编码设置问题. 对于第一个问题,目前个人发现只能通过重新建库解决,建库的 ...
- smbpasswd和pdbedit
samba用户管理: smbpasswd :smbpasswd命令属于samba套件,能够实现添加或删除samba用户和为用户修改密码. smbpasswd [options] USERNAME -a ...
- Ruby中的并行赋值和嵌套赋值
一. Ruby 的赋值实际是以并行方式执行的,所以赋值语句右边的值不受赋值语句本身的影响.在左边的任意一个变量或属性赋值之前,右边的值按他们出现的顺序被计算出来. 1.当赋值语句有多于一个左值时,赋值 ...
- Python-Redis的List操作
Redis列表是简单的字符串列表,一个列表可以包含超过40亿个元素 lpush(name,values):在name对应的list中添加元素,每个新的元素都添加到列表的最左边 rpush(name, ...
- Sql server 时间格式转化
--.SQL时间格式转化 --日期转换参数 ) --2009-03-15 15:10:02 ),'-',''),' ',''),':','') ) , ) --2009/03/15 ) , ) ) , ...
- 对vuex的理解
我用的vue安装了一个插件vuex插件 有3个 文件夹分别是actions(用于数据请求),getters(用于监听store),store(用于存储数据),
- 安装python Matplotlib 库
转:使用 python Matplotlib 库 绘图 及 相关问题 使用 python Matplotlib 库绘图 转:http://blog.csdn.net/daniel_ustc ...
- cygwin运行git submodule init出错error while loading shared libraries的解决
installing the Devel\gettext package should solve your problem. git-submodule requires that. Unfortu ...