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

思路就是每次加入一条边的时候,判断这条边是否存在过,存在过的话,就把那条边设为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. Poj 2328 Guessing Game(猜数字游戏)

    一.题目大意 两个小盆友玩猜数字游戏,一个小盆友心里想着1~10中的一个数字,另一个小盆友猜.如果猜的数字比实际的大,则告诉他"too high",小则"too low& ...

  2. Poj 1401 Factorial(计算N!尾数0的个数——质因数分解)

    一.Description The most important part of a GSM network is so called Base Transceiver Station (BTS). ...

  3. MongoDB分析工具之二:MongoDB分析器Profile

    MongoDB优化器profile 在MySQL 中,慢查询日志是经常作为我们优化数据库的依据,那在MongoDB 中是否有类似的功能呢?答案是肯定的,那就是MongoDB Database Prof ...

  4. PAT1106(BFS)

    PAT 1106 思路 BFS用在tree上,这一个题里主要关注的是用vector去保存每一个节点所连接的子节点,当BFS 时,一旦发现该节点下面没有子节点,这一层一定是最短的路径,然后用当前的层数去 ...

  5. css菜鸟之HTML 中块级元素设置 height:100% 的实现

    HTML 中块级元素设置 height:100% 的实现 当你设置一个页面元素的高度(height)为100%时,期望这样元素能撑满整个浏览器窗口的高度,但大多数情况下,这样的做法没有任何效果. 为什 ...

  6. 问题:webservice浏览后 无法输入参数;结果:调试Web Service时不能输入参数的解决办法

    使用.NET 开发Web Service,有一个很方便的功能就是可以通过IE直接测试Web Service.当你的Web Service的参数都是元数据类型,那么只要你使用IE浏览Web Servic ...

  7. mouseenter与mouseover的区别

    mouseover 事件:只有在鼠标指针穿过被选元素时,才会触发. mouseover 事件:鼠标指针穿过任何子元素,都会触发. 请看例子的演示.

  8. C/C++常用数学函数

    math.h/cmath(C++)数学函数库 1 三角函数    double sin (double);    double cos (double);    double tan (double) ...

  9. 关于Synchronized关键字锁住对象的嵌套问题

    如果在子关键字代码块中调用了sleep,是否会保留有所的锁?

  10. JDBC编程之数据更新

    -------------------siwuxie095                             JDBC 编程之数据更新             首先下载 MySQL 的 JDBC ...