【SSOJ2625: 哪些路不能修】題解
阿新 • • 發佈:2021-12-10
題目
一個有n個景點(入口)、m條單向道路的旅遊勝地,單向是不友好的,因為這會讓遊客走很多冤枉路,而且從同一個入口出發,往不同方向走,能遊玩的景點數目可能不同。於是,善良的Bob決定將道路全部改造成雙向的,讓每一個入口能逛的景點數量都確定下來,並製作景點數目表,讓遊客清楚地知道各個入口的景點數。但是,如果全部改成雙向邊之後,還需要修路,就可能導致景點數目表不正確。如果要景點數目表正確,請問哪些路是不能修的?
思路
這題的本質就是在求橋的數目。
求橋的話,就是套個模板,輸出時要記住不要前後倒轉輸出。
Code
#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; }