【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; 
}

posted @ 2021-12-09 22:03  zhangtingxi  阅读(36)  评论(0编辑  收藏  举报