poj 3207 2-SAT

题意:0-n-1围成一个环,给M条边,可以从外面连,也可以从内部连,问连玩之后能不想交的方案。

解法:2-sat,合理匹配方案

           i代表从内部连接第i条边,i+m代表从外部连接第I条边;

           如果C(i)=i+j,那么需要增加弧(-i,j),(-j,i),判断连通分量,如果选中连通分量中的一个点,那么需要选择连通分量中的所有点,如果c和c(i),在同一个连通分量内,则产生矛盾,此2-SAT无解。

         此题只需要判断有无解就好了。

          其实,我也不是很懂,多刷题吧。

    /*
    ----------------------------------

       Love is more than a word.
       It says so much.
       When I see these four letters,
       I almost feel your touch.
       This is only happened since
       I fell in love with you.
       Why this word does this,
       I haven't got a clue.

                       To My Goddess
                              CY
    ----------------------------------
    */

    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #include<cstdlib>
    #include<vector>
    #include<cmath>
    #include<stdlib.h>
    #include<iomanip>
    #include<list>
    #include<deque>
    #include<map>
    #include <stdio.h>
    #include <queue>

    #define maxn 500000+5

    #define ull unsigned long long
     #define ll long long
    #define reP(i,n) for(i=1;i<=n;i++)
     #define REP(i,a,b) for(i=a;i<=b;i++)
      #define rep(i,n) for(i=0;i<n;i++)

    #define cle(a) memset(a,0,sizeof(a))
     #define clehead(a) rep(i,maxn)a[i]=-1

    /*
      The time of story :
      **  while(1)
        {
             once upon a time,
             there was a mountain,
             on top of which there was a temple,
             in which there was an old monk and a little monk.
             Old monk was telling stories inside the temple.
             What was he talking about?
      **  }

       ÎûÎû
       (*^__^*)
    */

    #define sci(a) scanf("%d",&a)
     #define scd(a) scanf("%lf",&a)
      #define pri(a) printf("%d",a)
       #define prie(a) printf("%d\n",a)
        #define prd(a)  printf("%lf",a)
         #define prde(a) printf("%lf\n",a)
          #define pre printf("\n")

    #define LL(x) x<<1
     #define RR(x) x<<|1

    #define pb push_back
    #define mod 90001
    #define PI 3.141592657

    const ull INF = 1LL << 61;
    const int inf =   int(1e5)+10;
    const double eps=1e-5;

    using namespace std;

    struct node
    {
        int be;
       int to,w;
       int next;
    }edge[maxn];

    bool cmp(int a,int b){
        return a>b;
    }
    node cop[maxn];
    int head[maxn];
    int m;
    int low[maxn],dfn[maxn],stack[maxn],used[maxn];
    int cnt=0;
    int in[maxn],out[maxn];
    void add(int x,int y)
    {
        edge[cnt].be=x;
        edge[cnt].to=y;
        edge[cnt++].next=head[x];
        head[x]=(cnt-1);
    }
    void init()
    {
        memset(head,-1,sizeof(head));
        cle(used),cle(low),cle(dfn),cle(in),cle(out);
        m=0;
        cnt=0;
    }
    int tarbfs(int k,int lay,int &scc_num)
    {
        used[k]=1;
        low[k]=lay;
        dfn[k]=lay;
        stack[++m]=k;
        for(int i=head[k];i!=-1;i=edge[i].next)
        {
            if(used[edge[i].to]==0)
            {
                tarbfs(edge[i].to,++lay,scc_num);
            }
            if(used[edge[i].to]==1)
            {
                low[k]=min(low[k],low[edge[i].to]);
            }
        }
        if(dfn[k]==low[k])
        {
            ++scc_num;
            do{
                low[stack[m]]=scc_num;
                used[stack[m]]=2;
            }while(stack[m--]!=k);
        }
        return 0;
    }
    int main()
    {
        freopen("in.txt","r",stdin);
        //freopen("out.txt","w",stdout);
        int n,m;
        while(scanf("%d%d",&n,&m)!=EOF)
        {
            int i,j,k;
            init();
            rep(i,m)
            {
                scanf("%d%d",&cop[i].be,&cop[i].to);
                if(cop[i].be>cop[i].to)swap(cop[i].be,cop[i].to);
            }
            rep(i,m)
            {
                REP(j,i+1,m-1)
                {
                    if(cop[i].to>cop[j].be&&cop[i].to<cop[i].to&&cop[i].be<cop[j].be)
                    {
                        add(i+m,j),add(j,i+m),add(j+m,i),add(i,j+m);
                    }
                    if(cop[i].to>cop[j].to&&cop[i].be>cop[j].be&&cop[i].be<cop[j].to)
                    {
                         add(i+m,j),add(j,i+m),add(j+m,i),add(i,j+m);
                    }
                }
            }
            int scc_num=0;
            int lay=1;
            rep(i,2*m)
            {
                if(used[i]==0)
                {
                    tarbfs(i,lay,scc_num);
                }
            }
            bool flag=true;
            rep(i,m){
               if(low[i]==low[i+m]){
                   flag=false;
                  break;
               }
            }
            if(flag)
            {
                printf("panda is telling the truth...\n");
            }
            else {
                printf("the evil panda is lying again\n");
            }
        }
        return 0;
    }


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值