传送门:bzoj2199
权限题? 没关系,你洛上也有:洛谷- [USACO11JAN]大陆议会The Continental Cowngress
题解
一道2-SAT简单题。
只需要用到2-SAT连有向边的操作,拓扑排序和缩点都不需要,直接暴力找(非常之暴力)。
代码
#include<bits/stdc++.h>
using namespace std;
const int M=4e3+10,N=1e3+10;
int head[N<<1],to[M<<1],nxt[M<<1];
int x,y,n,m,cur,tot,ans[N],mark[N<<1];
char A,B;
inline int rd()
{
char ch=getchar();int x=0,f=1;
while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();}
while(isdigit(ch)){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
return x*f;
}
inline void lk(int u,int v)
{to[++tot]=v;nxt[tot]=head[u];head[u]=tot;}
inline void dfs(int x)
{
mark[x]=cur;
for(int i=head[x];i;i=nxt[i])
if(mark[to[i]]!=cur) dfs(to[i]);
}
inline int check(int x)
{
++cur;
dfs(x);
for(int i=1;i<=n;i++){
if(mark[i<<1]==cur && mark[i<<1|1]==cur)
return false;
}
return true;
}
int main(){
n=rd(),m=rd();
for(int i=1;i<=m;i++){
x=rd()<<1;cin>>A;y=rd()<<1;cin>>B;
if(A=='N') x++;if(B=='N') y++;
lk(x^1,y);lk(y^1,x);
}
for(int i=1;i<=n;i++){
x=check(i<<1),y=check(i<<1|1);
if(!x && !y){
printf("IMPOSSIBLE\n");return 0;
}
if(x) ans[i]= y? 2:0;else ans[i]=1;
}
for(int i=1;i<=n;i++){
switch(ans[i]){
case(0):putchar('Y');break;
case(1):putchar('N');break;
case(2):putchar('?');break;
}
}
return 0;
}