POJ 3207 Ikki's Story IV

来源:互联网 发布:java就业培训教程豆瓣 编辑:程序博客网 时间:2024/05/29 05:55

算是比较经典的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"); }
原创粉丝点击