题意比较短就不说了。
这题虽然直接暴力枚举就好,但是我这种刚学2-SAT还是有点吃力,,模型没转化出来= =
我们把议会方案数看作点对,然后把奶牛的意见看作冲突点,然后直接暴力就好了。。。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<cmath>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
int n, m;
const int N = 5e5 + 5;
int read()
{
int x = 0, f = 1; char ch = getchar();
while (ch<'0' || ch>'9') { if (ch == '-')f = -1; ch = getchar(); }
while (ch >= '0'&&ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }
return x*f;
}
int head[N], go[N], nxt[N],tot;
bool vis[N];
char ans[N];
inline void add(int x, int y)
{
go[++tot] = y;
nxt[tot] = head[x];
head[x] = tot;
}
inline void dfs(int x)
{
vis[x] = 1;
for (int i = head[x]; i; i = nxt[i])
{
int v = go[i];
if (!vis[v])dfs(v);
}
}
bool pd(int x)
{
memset(vis, 0, sizeof(vis));
dfs(x);
fd(i, n, 1)if (vis[i] && vis[i + n])return 0;
return 1;
}
int main()
{
n = read(), m = read();
fo(i, 1, m)
{
int a = read();
char x1, x2;
for ( x1 = getchar(); x1 != 'Y'&&x1 != 'N'; x1 = getchar());
if (x1 == 'N')a += n;
int b = read();
for ( x2 = getchar(); x2 != 'Y'&&x2 != 'N'; x2 = getchar());
if (x2 == 'N')b += n;
add(a > n ? a - n : a + n, b);
add(b > n ? b - n : b + n, a);
}
fo(i, 1, n)
{
bool bo1 = pd(i);
bool bo2 = pd(i + n);
if (bo1&&bo2)ans[i] = '?';
else if (bo1)ans[i] = 'Y';
else if (bo2)ans[i] = 'N';
else
{
printf("IMPOSSIBLE\n");
return 0;
}
}
fo(i, 1, n)putchar(ans[i]);
printf("\n");
}