link
solve
模板题,注意建边的方向决定了最后的判断
code
#include<cstdio>
#include<vector>
#include<stack>
const int maxn=1e6+5;
int n,m,vis[maxn<<1],low[maxn<<1],dfn[maxn<<1],tot,scc_cnt,color[maxn<<1];
std::vector<int> g[maxn<<1];
std::stack<int> stk;
inline int read(){
int ret=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-f;ch=getchar();}
while(ch<='9'&&ch>='0')ret=ret*10+ch-'0',ch=getchar();
return ret*f;
}
void tarjan(int u){
low[u]=dfn[u]=++tot;
stk.push(u);vis[u]=1;
for(int i=0;i<g[u].size();i++){
int v=g[u][i];
if(!dfn[v]){tarjan(v);low[u]=std::min(low[u],low[v]);}
else if(vis[v])low[u]=std::min(low[u],dfn[v]);
}
if(low[u]==dfn[u]){
++scc_cnt;
do{
color[u]=scc_cnt;
u=stk.top();stk.pop();vis[u]=0;
}while(low[u]!=dfn[u]);
}
}
int main(){
n = read(), m = read();
for (int i = 0; i < m; ++i) {
int a = read(), va = read(), b = read(), vb = read();
g[a + n * (va ^ 1)].push_back(b + n * (vb & 1));
g[b + n * (vb ^ 1)].push_back(a + n * (va & 1));
}
for(int i=1;i<=(n<<1);i++) (!dfn[i])&&(tarjan(i),0);
for(int i=1;i<=n;i++)
if(color[i]==color[i+n]){
puts("IMPOSSIBLE");
return 0;
}
puts("POSSIBLE");
for(int i=1;i<=n;i++)
printf("%d",color[i]>color[i+n]),putchar(' ');
return 0;
}