poj 3207 Ikki's Story IV - Panda's Trick


http://poj.org/problem?id=3207

一个圆上有n个点 m条连线(一个点最多只能连一条)

每条线可以走圆外 或 圆内 2-SAT问题

把每条边转化为两条即为A 和 A‘ 他们只能出现一个 然后把相交的直线视为 相斥 这样就转化成简单的2-SAT问题了

代码及其注释:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#define LL long long

using namespace std;

const int N=10005;
struct node
{
    struct tt *next;
}mem[N];
struct tt
{
    int j;
    struct tt *next;
};
struct ss
{
    int l1,l2;
}side[N];
int dfn[N];
int low[N];
bool in[N];
bool visited[N];
int deep;
int f[N];
stack<int>str;
void build(int i,int j)
{
    struct tt *t=new tt;
    t->j=j;
    t->next=mem[i].next;
    mem[i].next=t;
}
void Dele(int n)
{
    for(int i=0;i<=n;++i)
    mem[i].next=NULL;
}
bool X(int i,int j)//判断两边是否相交 l2>l1
{
    if(side[i].l1>side[j].l1&&side[i].l1<side[j].l2&&side[i].l2>side[j].l2)
    return true;
    if(side[j].l1>side[i].l1&&side[j].l1<side[i].l2&&side[j].l2>side[i].l2)
    return true;
    return false;
}
void Tarjan(int x)//求环加缩点
{
    visited[x]=true;
    str.push(x);
    in[x]=true;
    dfn[x]=low[x]=deep++;
    struct tt *t=mem[x].next;
    while(t!=NULL)
    {
        if(visited[t->j]==false)
        {
            Tarjan(t->j);
            low[x]=min(low[x],low[t->j]);
        }else if(in[t->j]==true)
        {
            low[x]=min(low[x],dfn[t->j]);
        }
        t=t->next;
    }
    if(low[x]==dfn[x])
    {
        while(str.top()!=x)
        {
            int k=str.top();
            str.pop();
            in[k]=false;
            f[k]=x;
        }
        int k=str.top();
        str.pop();
        in[k]=false;
        f[k]=x;
    }

}
int main()
{
    //freopen("data.txt","r",stdin);
    int n,m;
    while(scanf("%d %d",&n,&m)!=EOF)
    {
        for(int i=0;i<m;++i)
        {
            scanf("%d %d",&side[i].l1,&side[i].l2);
            if(side[i].l1>side[i].l2)
            swap(side[i].l1,side[i].l2);
            for(int j=0;j<i;++j)
            {
                if(X(i,j))
                {
                    build(j,i+m);//相斥建边
                    build(i,j+m);
                    build(j+m,i);
                    build(i+m,j);
                }
            }
        }
        while(!str.empty())
        str.pop();
        memset(dfn,-1,sizeof(dfn));
        memset(low,-1,sizeof(low));
        memset(in,false,sizeof(in));
        memset(visited,false,sizeof(visited));
        deep=0;
        for(int i=0;i<m*2;++i)
        {
            if(visited[i]==false)//遍历
            Tarjan(i);
        }
        int l;
        for(l=0;l<m;++l)
        if(f[l]==f[l+m])//一个对应属于同一个环 则break
        break;
        if(l<m)
        printf("the evil panda is lying again\n");
        else
        printf("panda is telling the truth...\n");
        Dele(2*m);
    }
    return 0;
}

  

优质内容筛选与推荐>>
1、Python开发者的6个必备库
2、Nginx配置HTTPS强制跳转到HTTP
3、P1201[USACO1.1]贪婪的送礼者GreedyGiftGivers
4、【开源公告】微信后台Phx系列开源
5、iOS开发·第三方网络下载处理框架:AFNetworking网络下载处理(官方文档翻译篇)


长按二维码向我转账

受苹果公司新规定影响,微信 iOS 版的赞赏功能被关闭,可通过二维码转账支持公众号。

    阅读
    好看
    已推荐到看一看
    你的朋友可以在“发现”-“看一看”看到你认为好看的文章。
    已取消,“好看”想法已同步删除
    已推荐到看一看 和朋友分享想法
    最多200字,当前共 发送

    已发送

    朋友将在看一看看到

    确定
    分享你的想法...
    取消

    分享想法到看一看

    确定
    最多200字,当前共

    发送中

    网络异常,请稍后重试

    微信扫一扫
    关注该公众号