poj 3207 Ikki's Story IV - Panda's Trick(2-sat)

来源:互联网 发布:linux 监控java堆内存 编辑:程序博客网 时间:2024/04/29 09:42

题目链接:http://poj.org/problem?id=3207

题意:在圆上有n个点,编号为0到n-1,按顺序排列,现在要在连m条线,线必须完全在圆的内部或外部,所有的线不能相交,问是否存在连的方法。

解析:每条线只有两种状态,在内部或外部,即0或1,可以用2-sat来搞,在圆上有交叉的两条线为矛盾条件。

参考代码:

#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>using namespace std;#define clr(a,b) memset(a,b,sizeof(a))const int M = 1005;struct Node{int u,v;}node[M];int h[M],num[M*M],nex[M*M],pos;int low[M],dfn[M],Stack[M],connect[M],ConnectNum,top,ind;bool InStack[M];void init(){    ConnectNum = 0;    top = ind = 0;    pos = 0;    clr(h,-1);    clr(dfn,0);    clr(InStack,false);    clr(connect,0);    clr(low,0);}void add(int u,int v){    num[pos] = v;    nex[pos] = h[u];    h[u] = pos++;}void tarjin(int x){    dfn[x] = low[x] = ++ind;    InStack[x] = true;    Stack[++top] = x;    for(int i = h[x];i != -1;i = nex[i])    {        if(!dfn[ num[i] ])        {            tarjin(num[i]);            low[x] = min(low[x],low[ num[i] ]);        }        else if(InStack[ num[i] ])        {            low[x] = min(low[x],dfn[ num[i] ]);        }    }    if(dfn[x] == low[x])    {        int s;        ConnectNum++;        do{            s = Stack[top--];            connect[s] = ConnectNum;            InStack[s] = false;        }while(s != x);    }}bool solve(int n){    for(int i = 0;i < n*2;++i)    {        if(!dfn[i]) tarjin(i);    }    for(int i = 0;i < n;++i)    {        if(connect[i] == connect[i+n] && connect[i])        {            return false;        }    }    return true;}int main(){    int m,n;    while(cin>>n>>m)    {        init();        int u,v;        for(int i = 0;i < m;++i)        {            cin>>node[i].u>>node[i].v;if(node[i].u > node[i].v)swap(node[i].u,node[i].v);        }for(int i = 0;i < m;++i){for(int j = i+1;j < m;++j){int cnt = 0;if(node[j].u <= node[i].v && node[j].u >= node[i].u)cnt++;if(node[j].v <= node[i].v && node[j].v >= node[i].u)cnt++;if(cnt&1){add(i,j+m);add(j,i+m);add(i+m,j);add(j+m,i);}}}        if(solve(m)) cout<<"panda is telling the truth..."<<endl;        else cout<<"the evil panda is lying again"<<endl;}    return 0;}


原创粉丝点击