jzoj3796 【NOIP2014模拟8.21】议案决定

【NOIP2014模拟8.21】议案决定 (Standard IO)

Description

小C在玩一个游戏,在游戏中他扮演国王的角色。国王手下有M个大臣,他们有一天对国王要处理的N件事务进行投票。每个大臣可以对两件事务进行投票(赞成或反对),格式如下:x c_x y c_y(x, y为整数,c_x, c_y为“Y”(表示赞成)或“N”(表示反对)(不含双引号),表示这个大臣对事务x的态度为c_x,对事务y的态度为c_y)。这些大臣非常难以对付,如果国王的决定和某个大臣的两个意见都不同,那么这个大臣就会离开国王。小C认为不能让任何一个大臣离开国王,否则国王就无法正常地处理自己的事务。请你帮助小C做个决定。

Input

第一行,两个整数N, M。
接下来的M行,每行表示一个大臣的投票。

Output

如果小C无论如何都只能让至少一个大臣离开国王,则输出“IMPOSSIBLE”(不含双引号),否则输出一个长度为N的字符串,如果第i件事务必须赞成,则第i个字符为“Y”;如果第i件事务必须反对,则第i个字符为“N”,否则第i个字符为“?”。

Sample Input

3 4
1 Y 2 N
1 N 2 N
1 Y 3 Y
1 Y 2 Y

Sample Output

YN?

扫描二维码关注公众号,回复: 751551 查看本文章

Data Constraint

对于50%的数据,1<=N<=10,1<=M<=40;
对于全部的数据,1<=N<=1000,1<=M<=4000。

分析:一个2-SAT问题
可以用dfs解决。如果对某个事务赞成就必须对该事务反对(记为事件A),且对某个事务反对就必须对该事务赞成(记为事件B),则不可能满足所有条件。否则:
若事件A成立,则对该事务必须反对。
若事件B成立,则对该事务必须赞成。

代码

#include <cstdio>
#include <cstring>
#include <iostream>
#define N 5000
using namespace std;

struct arr
{
    int to,nxt;
}a[N*5];
int n,m,l,ls[N];
bool v[N];
char ch[N];

void add(int x,int y) {a[++l].to=y;a[l].nxt=ls[x];ls[x]=l;}

int check(int x)
{
    v[x]=true;
    for (int i=ls[x];i;i=a[i].nxt)
    {
        int y=a[i].to;
        if (!v[y])
        {
            if (y%2)
                if (v[y+1]) return 0;
            if (!(y%2))
                if (v[y-1]) return 0;
            if (!check(y)) return 0;
        }
    }
    return 1;
}

int main()
{
    scanf("%d%d",&n,&m);
    for (int i=1;i<=m;i++)
    {
        int x,y;
        char c1,c2;
        cin>>x>>c1>>y>>c2;
        if (c1=='Y')
        {
            if (c2=='Y') add(x*2,y*2-1),add(y*2,x*2-1);
            if (c2=='N') add(x*2,y*2),add(y*2-1,x*2-1);
        }
        else 
        {
            if (c2=='Y') add(x*2-1,y*2-1),add(y*2,x*2);
            if (c2=='N') add(x*2-1,y*2),add(y*2-1,x*2);
        }
    }
    bool fl=false;
    for (int i=1;i<=n;i++)
    {
        memset(v,false,sizeof(v));
        int p1=check(i*2-1);
        memset(v,false,sizeof(v));
        int p2=check(i*2);
        if (p1&&p2) ch[i]='?';
        if (p1&&!p2) ch[i]='Y';
        if (!p1&&p2) ch[i]='N';
        if (!p1&&!p2) fl=true;
    }
    if (fl) printf("IMPOSSIBLE"); else
    for (int i=1;i<=n;i++)
        printf("%c",ch[i]);
}

猜你喜欢

转载自blog.csdn.net/zhanghaoxian1/article/details/79264823