原题解链接:https://ac.nowcoder.com/discuss/149978
出一棵生成树,令所有树边从父亲指向儿子,所有返祖边从后代指向祖先。
判断这样构造的有向图是否强连通即可。
正确性证明如下:
如果无向图不连通或者存在割边显然无解,
否则这样构造一定是一组解。
因为考虑 求割边的过程,不存在割边就意味着每个点都能走回他的祖先,
所以在这样构造的有向图里,每个点也依旧能走回他的祖先。
#include<bits/stdc++.h>
using namespace std;
template <typename T> void chmin(T &x,const T &y)
{
if(x>y)x=y;
}
#define rep(i,l,r) for(int i=l;i<=r;++i)
const int N=1e6+5,M=1e6+5;
int t[N];
struct Edge
{
int to,next;
};
Edge l[M*2];
int dfn[N],low[N],tot;
bool b[M];
void out()
{
puts("impossible");
exit(0);
}
void dfs(int x,int fr)
{
dfn[x]=low[x]=++tot;
for(int i=t[x];i;i=l[i].next)
{
int y=l[i].to;
if(y==fr)continue;
if(dfn[y])
{
chmin(low[x],low[y]);
if(dfn[y]<dfn[x])b[i/2]=i%2^1;
}
else
{
b[i/2]=i%2^1;
dfs(y,x);
chmin(low[x],low[y]);
}
}
}
int main()
{
int n,m;
cin>>n>>m;
rep(i,1,m)
{
int x,y;
scanf("%d%d",&x,&y);
l[i*2]=(Edge){y,t[x]};t[x]=i*2;
l[i*2+1]=(Edge){x,t[y]};t[y]=i*2+1;
}
dfs(1,0);
rep(i,2,n)
if(low[i]>=dfn[i])out();
rep(i,1,m)putchar('0'+b[i]);
}