首页 > 代码库 > POJ Ikki's Story IV - Panda's Trick [2-SAT]

POJ Ikki's Story IV - Panda's Trick [2-SAT]

题意:

圆上n个点,m对点之间连边,连在园内或园外,所有边不相交是否可行


 

发现两对点连线都在内相交则都在外也相交,那么只有一个在内一个在外啦,转化为$2-SAT$问题

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>using namespace std;const int N=1005,M=5e5;typedef long long ll;inline int read(){    char c=getchar();int x=0,f=1;    while(c<0||c>9){if(c==-)f=-1;c=getchar();}    while(c>=0&&c<=9){x=x*10+c-0;c=getchar();}    return x*f;}int n,m,a[N],b[N];struct edge{    int v,ne;}e[M];int h[N],cnt=0;inline void ins(int u,int v){    cnt++;    e[cnt].v=v;e[cnt].ne=h[u];h[u]=cnt;}void buildGraph(){    for(int i=1;i<=m;i++)        for(int j=1;j<=m;j++)             if((a[i]<a[j]&&a[j]<b[i]&&b[i]<b[j])||(a[j]<a[i]&&a[i]<b[j]&&b[j]<b[i])){                int x=i<<1,y=j<<1;                ins(x,y-1);ins(y-1,x);                ins(x-1,y);ins(y,x-1);            }    }int dfn[N],low[N],dfc,belong[N],scc;int st[N],top;void dfs(int u){    dfn[u]=low[u]=++dfc;    st[++top]=u;    for(int i=h[u];i;i=e[i].ne){        int v=e[i].v;        if(!dfn[v]){            dfs(v);            low[u]=min(low[u],low[v]);        }else if(!belong[v])            low[u]=min(low[u],dfn[v]);    }    if(dfn[u]==low[u]){        scc++;        while(true){            int x=st[top--];            belong[x]=scc;            if(x==u) break;        }    }}bool judge(){    for(int i=1;i<=m;i++) if(belong[i<<1]==belong[(i<<1)-1]) return false;    return true;}int main(){    freopen("in","r",stdin);    n=read();m=read();    for(int i=1;i<=m;i++){        a[i]=read(),b[i]=read();        if(a[i]>b[i]) swap(a[i],b[i]);    }    buildGraph();    int _=m<<1;    for(int i=1;i<=_;i++) if(!dfn[i]) dfs(i);    if(judge()) puts("panda is telling the truth...");    else puts("the evil panda is lying again");}

 

POJ Ikki's Story IV - Panda's Trick [2-SAT]