1. 程式人生 > 其它 >【SSOJ2625: 哪些路不能修】題解

【SSOJ2625: 哪些路不能修】題解

題目

一個有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; 
}