本文搬运自本人初中博客园博客,若图片加载不出来,可到原文查看:https://www.cnblogs.com/zhangtingxi/p/15669522.html

题目

一个有n个景点(入口)、m条单向道路的旅游胜地,单向是不友好的,因为这会让游客走很多冤枉路,而且从同一个入口出发,往不同方向走,能游玩的景点数目可能不同。于是,善良的Bob决定将道路全部改造成双向的,让每一个入口能逛的景点数量都确定下来,并制作景点数目表,让游客清楚地知道各个入口的景点数。但是,如果全部改成双向边之后,还需要修路,就可能导致景点数目表不正确。如果要景点数目表正确,请问哪些路是不能修的?

思路

这题的本质就是在求桥的数目。

求桥的话,就是套个模板,输出时要记住不要前后倒转输出。

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#include<bits/stdc++.h>
using namespace std;
//#define int long long
inline int read(){int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;
ch=getchar();}while(ch>='0'&&ch<='9'){x=(x<<1)+
(x<<3)+(ch^48);ch=getchar();}return x*f;}
//#define M
//#define mo
#define N 100010
struct node
{
int x, y, n;
}d[N*6];
int n, m, i, j, k;
int f[N], c[N*6], h[N], dep[N];
int u, v;

int fa(int x)
{
if(f[x]==x) return x;
return f[x]=fa(f[x]);
}

void dfs(int x)
{
for(int g=h[x]; g; g=d[g].n)
{
if(c[g]) continue;
c[g]=c[((g-1)^1)+1]=1;
int y=d[g].y;
if(!dep[y])
{
dep[y]=dep[x]+1;
dfs(y);
}
if(dep[fa(y)]>0)
{
if(dep[fa(y)]<dep[fa(x)]) f[f[x]]=f[y];
else f[f[y]]=f[x];
}

}
dep[x]=-1;
}

void cun(int x, int y)
{
d[++k].x=x; d[k].y=y;
d[k].n=h[x]; h[x]=k;
}

signed main()
{
// freopen("tiaoshi.in", "r", stdin);
// freopen("tiaoshi.out", "w", stdout);
n=read(); m=read();
for(i=1; i<=m; ++i)
{
u=read(); v=read();
cun(u, v); cun(v, u);
}
for(i=1; i<=n; ++i) f[i]=i;
for(i=1; i<=n; ++i)
if(!dep[i]) dep[i]=1, dfs(i);
for(i=1; i<=n; ++i) fa(i);
for(i=1, k=0; i<=m; ++i)
if(f[d[i*2].x]!=f[d[i*2].y]) printf("%d %d\n", d[i*2].y, d[i*2].x);
return 0;
}