解题思路
设x,x^1互为反命题,那么对于一张投票(x,y),若不选x则一定选y,不选y一定选x,所以连x^1->y,y^1->x两条边。
连出这个图之后,判断每一个点能不能选。也就是说,判断这个点所有能到达的点是否存在冲突(同一类的Y和N都选了),dfs就可以 。
如果某一个议案的Y和N都不能选,那么IMPOSSIBLE
否则的话,如果某一个点不能选,那么它同类不同项的那个点必须选;否则的话这两个点选不选都行。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<ctime>
#include<vector>
using namespace std;
int getint()
{
int i=0,f=1;char c;
for(c=getchar();(c<'0'||c>'9')&&c!='-';c=getchar());
if(c=='-')c=getchar(),f=-1;
for(;c>='0'&&c<='9';c=getchar())i=(i<<3)+(i<<1)+c-'0';
return i*f;
}
const int N=2005;
int n,m;
bool visit[N],ok[N];
vector<int>g[N];
int p(int x,char c)
{
return c=='Y'?x-1<<1:(x-1<<1)+1;
}
void dfs(int u)
{
visit[u]=true;
for(int e=0;e<g[u].size();e++)
{
int v=g[u][e];
if(!visit[v])dfs(v);
}
}
int main()
{
//freopen("lx.in","r",stdin);
int x,y;
char c1,c2;
n=getint(),m=getint();
while(m--)
{
x=getint();
for(c1=getchar();c1!='Y'&&c1!='N';c1=getchar());
y=getint();
for(c2=getchar();c2!='Y'&&c2!='N';c2=getchar());
x=p(x,c1),y=p(y,c2);
g[x^1].push_back(y);
g[y^1].push_back(x);
}
memset(ok,true,sizeof(ok));
for(int i=0;i<2*n;i++)
{
memset(visit,false,sizeof(visit));
dfs(i);
for(int j=0;j<2*n;j++)
if(visit[j]&&visit[j^1])
{
ok[i]=false;
break;
}
if(!ok[i]&&!ok[i^1])
{
cout<<"IMPOSSIBLE";
return 0;
}
}
for(int i=1;i<=n;i++)
{
if(!ok[p(i,'Y')])cout<<"N";
else if(!ok[p(i,'N')])cout<<"Y";
else cout<<"?";
}
return 0;
}