[BZOJ2199][Usaco2011 Jan]奶牛议会(2-SAT)

8 篇文章 0 订阅

题目描述

传送门

题解

2-SAT,和满汉全席差不多
如果一个奶牛的投票是id x jd y的话,那么就连边id x^1->jd y(^表示同一类的不同项)
连出这个图之后,判断每一个点能不能选。也就是说,判断这个点所有能到达的点是否存在冲突(同一类的Y和N都选了),dfs就可以
如果某一类的Y和N都不能选,那么IMPOSSIBLE
否则的话,如果某一个点不能选,那么它同类不同项的那个点必须选;否则的话这两个点选不选都行

代码

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
#define N 2005

char s1,s2;
int n,m,id,jd,x,y,cnt;
int tot,point[N],nxt[N*4],v[N*4];
int pt[N][2],chose[N],can[N];
bool vis[N];

void add(int x,int y)
{
    ++tot; nxt[tot]=point[x]; point[x]=tot; v[tot]=y;
}
bool pd(int x,int fa)
{
    if (chose[x^1]) return 0;
    vis[x]=1;
    chose[x]=1;
    for (int i=point[x];i;i=nxt[i])
        if (!vis[v[i]])
        {
            int now=pd(v[i],x);
            if (!now) return 0;
        }
    return 1;
}
int main()
{
    scanf("%d%d\n",&n,&m);
    for (int i=1;i<=n;++i) pt[i][0]=cnt++,pt[i][1]=cnt++;
    for (int i=1;i<=m;++i)
    {
        scanf("%d %c %d %c\n",&id,&s1,&jd,&s2);
        if (s1=='Y') x=0; else x=1;
        if (s2=='Y') y=0; else y=1;
        add(pt[id][x^1],pt[jd][y]);
        add(pt[jd][y^1],pt[id][x]);
    }
    for (int i=0;i<2*n;++i)
    {
        memset(chose,0,sizeof(chose));
        memset(vis,0,sizeof(vis));
        can[i]=pd(i,0);
    }
    for (int i=1;i<=n;++i)
        if (!can[pt[i][0]]&&!can[pt[i][1]])
        {
            puts("IMPOSSIBLE");
            return 0;
        }
    memset(chose,0,sizeof(chose));
    for (int i=0;i<2*n;++i)
        if (!can[i]) chose[i]=-1,chose[i^1]=1;
    for (int i=1;i<=n;++i)
        if (chose[pt[i][0]]==1) putchar('Y');
        else if (chose[pt[i][1]]==1) putchar('N');
        else putchar('?');
    puts("");
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值