版权声明:本文为博主原创文章,未经博主允许必须转载。 https://blog.csdn.net/qq_35950004/article/details/82562478
不需要反向建边,不需要拓扑排序。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cctype>
#define maxn 2000005
using namespace std;
int n,m;
int info[maxn],Prev[maxn<<1],to[maxn<<1],cnt_e;
inline void Node(const int &u,const int &v){ Prev[++cnt_e]=info[u],info[u]=cnt_e,to[cnt_e]=v; }
int dfn[maxn],low[maxn],tot,c[maxn],scc,q[maxn],tp;
void dfs(int now)
{
dfn[now] = low[now] = ++tot;
q[tp++] = now;
for(int i=info[now];i;i=Prev[i])
if(!dfn[to[i]]) dfs(to[i]) , low[now] = min(low[now] , low[to[i]]);
else if(!c[to[i]]) low[now] = min(low[now] , dfn[to[i]]);
if(dfn[now] == low[now])
{
int tmp = -1; scc++;
for(;tmp != now;)
c[tmp = q[--tp]] = scc;
}
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1,a,b,u,v;i<=m;i++)
{
scanf("%d%d%d%d",&a,&u,&b,&v);
Node(a<<1|(!u) , b<<1|v);
Node(b<<1|(!v) , a<<1|u);
}
for(int i=2;i<=(n<<1|1);i++) if(!dfn[i]) dfs(i);
for(int i=1;i<=n;i++) if(c[i<<1]==c[i<<1|1]){ puts("IMPOSSIBLE");return 0; }
puts("POSSIBLE");
for(int i=1;i<n;i++)
if(c[i<<1] < c[i<<1|1]) printf("0 ");
else printf("1 ");
if(c[n<<1] < c[n<<1|1]) printf("0\n");
else printf("1\n");
}