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 ...
随机推荐
- POJ(2186)强连通分量分解
#include<cstdio> #include<vector> #include<cstring> using namespace std; ; vector& ...
- 三、kafka主要配置
1.Broker配置 <ignore_js_op> 2.Consumer主要配置 <ignore_js_op> 3.Producer主要配置 <ignor ...
- js数组中的reverse()方法
reverse方法是将数组中的元素的顺序进行反转,在原数组上操作,然后返回原数组.由于本人是学习js的新人,对reverse函数进行了几个小实验,以下实验均在Chrome浏览器上运行 实验一:reve ...
- centos6.5安装tomcat7.0教程(二)
阅读之前对基本命不熟悉的话, 可以先安装另一文章: http://www.cnblogs.com/duenboa/articles/6665159.html把基本的命令记一下.后面的文章就不重复演示了 ...
- 《精通Spring4.X企业应用开发实战》读后感第六章(国际化)
- p4503&bzoj3555 企鹅QQ
传送门(洛谷) 传送门(bzoj) 题目 PenguinQQ是中国最大.最具影响力的SNS(Social Networking Services)网站,以实名制为基础,为用户提供日志.群.即时通讯.相 ...
- iOS开发中,修改ASIHTTPRequest源码,禁止在POST时URL编码
通过ASIHTTPRequest库进行POST时,会对POST的文本内容进行encodeURL,而且ASIHTTPRequest自身并没有配置项可以关闭这个转换. 本文提供一个方法关闭encodeUR ...
- Spring入门第一课
今天先不讲Spring是什么. Spring网址:http://projects.spring.io/spring-framework/ Eclipse 安装开发IDE 在Eclipse Market ...
- vivado中如何调用chipscope或者impact
vivado中并没有集成chipscope和impact,所以需要安装ISE,安装完ISE后进行以下操作: 1) 选择环境变量中的系统变量,新建以下变量 XILINX ...
- redis系列:redis介绍与安装
前言 这个redis系列的文章将会记录博主学习redis的过程.基本上现在的互联网公司都会用到redis,所以学习这门技术于你于我都是有帮助的. 博主在写这个系列是用的是目前最新版本4.0.10,虚拟 ...