POJ 3207 Ikki's Story IV - Panda's Trick 2-SAT

5 篇文章 0 订阅

算是比较经典的2-SAT模型了吧。
题意很多人都没说清楚,我这里贴一个别人的题解,这里面的说的很好。
http://blog.csdn.net/l04205613/article/details/6668318
2-sat直接上,连边的时候直接把a1

#include<cstdio>
#include<algorithm>
#include<cstring>
#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;
const int N=5e5+5;
int n,m;
int a[N],b[N],head[N],next[N],go[N];
bool ins[N];
int low[N],dfn[N],stk[N];
int top,tim,bl,tot,block[N];
inline void tarjan(int x)
{
    dfn[x]=low[x]=++tim;
    stk[++top]=x;
    ins[x]=1;
    for(int i=head[x];i;i=next[i])
    {
        int v=go[i];
        if (!dfn[v])
        {
            tarjan(v);
            low[x]=min(low[x],low[v]);
        }
        else if (ins[v])low[x]=min(dfn[v],low[x]);
    } 
    if (dfn[x]==low[x])
    {
        bl++;
        int j=0;
        while (j!=x)
        {
            j=stk[top--];
            block[j]=bl;
            ins[j]=0;
        }
    }
}
inline bool jud()
{
    fo(i,1,m)
    if (block[2*i]==block[2*i-1])return 0;
    return 1;
}
inline void add(int x,int y)
{
    go[++tot]=y;
    next[tot]=head[x];
    head[x]=tot;
}
inline void build()
{
    fo(i,1,m)
    fo(j,i+1,m)
    if ((a[i]<a[j]&&a[j]<b[i]&&b[j]>b[i])||(a[j]<a[i]&&a[i]<b[j]&&b[i]>b[j]))
    {
        add(2*i-1,2*j);
        add(2*j,2*i-1);
        add(2*j-1,2*i);
        add(2*i,2*j-1);
    }
}
int main()
{
    scanf("%d%d",&n,&m);
    fo(i,1,m)
    {
        scanf("%d%d",&a[i],&b[i]);
        if (a[i]>b[i])swap(a[i],b[i]);
    }
    build();
    fo(i,1,2*m)if (!dfn[i])tarjan(i);
    if (jud())puts("panda is telling the truth...");
    else puts("the evil panda is lying again"); 
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值