• Go Deeper(2010成都现场赛题)(2-sat)


    G - Go Deeper
    Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu

    Description

    Here is a procedure's pseudocode:

     
    	   go(int dep, int n, int m)  
    	   begin  
    	      output the value of dep. 
    	      if dep < m and x[a[dep]] + x[b[dep]] != c[dep] then go(dep + 1, n, m)
    	   end 
    	 

    In this code n is an integer. abc and x are 4 arrays of integers. The index of array always starts from 0. Array a and b consist of non-negative integers smaller than n. Array x consists of only 0 and 1. Array c consists of only 0, 1 and 2. The lengths of array ab and c are mwhile the length of array x is n.

    Given the elements of array ab, and c, when we call the procedure go(0, n , m) what is the maximal possible value does the procedure output?

    Input

    There are multiple test cases. The first line of input is an integer T (0 < T ≤ 100), indicating the number of test cases. Then T test cases follow. Each case starts with a line of 2 integers n and m (0 < n ≤ 200, 0 < m ≤ 10000). Then m lines of 3 integers follow. The i-th(1 ≤ i ≤m) line of them are ai-1 ,bi-1 and ci-1 (0 ≤ ai-1bi-1 < n, 0 ≤ ci-1 ≤ 2).

    Output

    For each test case, output the result in a single line.

    Sample Input

    3
    2 1
    0 1 0
    2 1
    0 0 0
    2 2
    0 1 0
    1 1 2
    
    

    Sample Output

    1
    1
    2

    题目大意:
     
    给定一些方程,x[]数组未知,求前面最多能够有多少方程x[a]+x[b]!=c能够被满足。
     其中 c=0,1,2
      x[]={0,1}
    相当于裸的2sat问题,加上二分
      
      强烈建议阅读 kuangbin大神对2-sat的总结:http://www.cnblogs.com/kuangbin/archive/2012/10/05/2712429.html

    总的来说,就是当 a or b 时 连接 a' -> b 与 b' -> a 的边,然后进行强连通判断是否出现 a 与 a' ...在同一个连通分量中,若在则不可能。

    建立数a的两个状态,即a与a',相当于x[a]=1 和 x[a']=0

    x[a]+x[b]!=0 => a or b => a'->b 且 a->b'
    x[a]+x[b]!=1 => (a and b) or (a' and b') == a or b' 且 a' or b => a'->b' 且 b->a 且 a->b 且 b'->a
    x[a]+x[b]!=2 => a' or b' => a->b' 且 a'->b

    按上面来建图判断即可

    #include<cstdio>
    #include<cstring>
    int e[50000],pd[50000],be[800],ne[50000],all;
    int dfn[800],low[800],instack[800],belong[800],stack[800],stak,curr,num;
    int a,b,c,n,m,l,r,mid,flag;
    void add(int x,int y,int p){
        e[++all]=y;
        pd[all]=p;
        ne[all]=be[x];
        be[x]=all;
    }
    void tarjan(int x){
        instack[x]=1;
        stack[++stak]=x;
        dfn[x]=low[x]=++curr;
        for(int j=be[x];j!=0;j=ne[j])
        if(pd[j]<=mid){
            if(!dfn[e[j]]){
                tarjan(e[j]);
                if(low[x]>low[e[j]]) low[x]=low[e[j]];
            }else if(instack[e[j]]&&low[x]>low[e[j]])
                low[x]=low[e[j]];
        }
        if(dfn[x]==low[x]){
            int j;
            ++num;
            do{
                j=stack[stak--];
                instack[j]=0;
                belong[j]=num;
            }while(j!=x);
        }
    }
    int solve(){
        curr=stak=num=0;
        memset(dfn,0,sizeof(dfn));
        memset(low,0,sizeof(low));
        memset(instack,0,sizeof(instack));
        for(int i=0;i<2*n;i++)
            if(!dfn[i]) tarjan(i);
        flag=0;
        for(int i=0;i<n;i++)
            if(belong[2*i]==belong[2*i+1]){
                flag=1;
                break;
            }
        return flag;
    }
    int main()
    {
        int tt;
        scanf("%d",&tt);
        while(tt--){
            scanf("%d%d",&n,&m);
            all=0;
            memset(e,0,sizeof(e));
            memset(be,0,sizeof(be));
            memset(ne,0,sizeof(ne));
            memset(pd,0,sizeof(pd));
            for(int i=0;i<m;i++){
                scanf("%d%d%d",&a,&b,&c);
                switch (c){
                case 0: add(2*a+1,2*b,i);
                        add(2*b+1,2*a,i);
                        break;
                case 1: add(2*a,2*b,i);
                        add(2*b+1,2*a+1,i);
                        add(2*b,2*a,i);
                        add(2*a+1,2*b+1,i);
                        break;
                case 2: add(2*a,2*b+1,i);
                        add(2*b,2*a+1,i);
                        break;
                }
            }
            l=0;r=m-1;
            while(l<r-1){
                mid=(l+r)/2;
                if(solve()) r=mid; else l=mid;
            }
            mid=r;
            if(!solve()) printf("%d
    ",r+1);
            else printf("%d
    ",l+1);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    CentOS7 FTP安装与配置
    linux CentOS 安装 nginx
    linux CentOS YUM 安装 nginx+tomcat+java+mysql运行环境
    Node.js 开发
    Nginx 负载均衡
    BtxCMS.Net 项目
    不得不看!史上最全的三十多张架构师图谱!
    高危群体:开发者的自白,躲坑,迷茫,和下一步
    p2p-如何拯救k8s镜像分发的阿喀琉斯之踵
    Tower与DevCloud对比分析报告
  • 原文地址:https://www.cnblogs.com/Mathics/p/3866886.html
Copyright © 2020-2023  润新知