zoukankan      html  css  js  c++  java
  • Go Deeper

    Go Deeper

    Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
    Total Submission(s): 21 Accepted Submission(s): 10
     
    Problem 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. a, b, c 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 a, b and c are m while the length of array x is n. Given the elements of array a, b, and c, when we call the procedure go(0, n, m) what is the maximal possible value the procedure may 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-1, bi-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
     
    Author
    CAO, Peng
     
    Source
    The 2010 ACM-ICPC Asia Chengdu Regional Contest
     
    Recommend
    zhouzeyong
     
    /*
    题意:给出递归函数:
        void go(int dep, int n, int m){
            printf("%d
    ",dep);
            if(dep<m&&x[a[dep]]+x[b[dep]]!=c[dep])
                go(dep + 1, n, m);
        }
        其中,a,b数组的元素小于n 数组长度为m,c数组的元素只有 0,1,2 数组长度为m, x数组的元素只有0,1现在给出a,b,c
        数组的元素,问你这个输出的dep最大是多少,也就是递归最多的次数。
        
    初步思路:分析条件:dep<m&&x[a[dep]]+x[b[dep]]!=c[dep] m是最大可能的递归次数,并且x[a[dep]]+x[b[dep]]!=c[dep]
        实际上是x[a[dep]]+x[b[dep]]和c[dep]是不能共存的,也就是说有如下几种情况:
            c[dep]==0:x[a[dep]]和x[b[dep]],必定至少有一个为真
            c[dep]==1:x[a[dep]]和x[b[dep]],只能都为真都为假
            c[dep]==2:x[a[dep]]和x[b[dep]],不能都为真
        由上面三种情况,二分递归的次数,判断的规则就是2-SAT跑的结果
    */
    #include<bits/stdc++.h>
    using namespace std;
    int t;
    int n,m;
    int a[10010],b[10010],c[10010],x[210];
    /*********************************************2-SAT模板*********************************************/
    const int maxn=10000+10;
    struct TwoSAT
    {
        int n;//原始图的节点数(未翻倍)
        vector<int> G[maxn*2];//G[i].j表示如果mark[i]=true,那么mark[j]也要=true
        bool mark[maxn*2];//标记
        int S[maxn*2],c;//S和c用来记录一次dfs遍历的所有节点编号
    
        //从x执行dfs遍历,途径的所有点都标记
        //如果不能标记,那么返回false
        bool dfs(int x)
        {
            if(mark[x^1]) return false;//这两句的位置不能调换
            if(mark[x]) return true;
            mark[x]=true;
            S[c++]=x;
            for(int i=0;i<G[x].size();i++)
                if(!dfs(G[x][i])) return false;
            return true;
        }
        
        void init(int n)
        {
            this->n=n;
            for(int i=0;i<2*n;i++) 
                G[i].clear();
            memset(mark,0,sizeof(mark));
        }
    
        //加入(x,xval)或(y,yval)条件
        //xval=0表示假,yval=1表示真
        void add_clause(int x,int xval,int y,int yval)//这个地方不是一尘不变的,而是参照问题的约束条件进行加边
        {
            G[2*x+xval].push_back(y*2+yval);
        }
    
        //判断当前2-SAT问题是否有解
        bool solve()
        {
            for(int i=0;i<2*n;i+=2)
            if(!mark[i] && !mark[i+1])
            {
                c=0;
                if(!dfs(i))
                {
                    while(c>0) mark[S[--c]]=false;
                    if(!dfs(i+1)) return false;
                }
            }
            return true;
        }
    }TS;
    /*********************************************2-SAT模板*********************************************/
    void build(int mid){
        TS.init(n);
        for(int i=0;i<mid;i++){
            switch(c[i]){
                case 0:
                    TS.add_clause(a[i],0,b[i],1);
                    TS.add_clause(b[i],0,a[i],1);
                    break;//不能都为假
                case 1:
                    TS.add_clause(a[i],0,b[i],0);
                    TS.add_clause(b[i],0,a[i],0);
                    TS.add_clause(a[i],1,b[i],1);
                    TS.add_clause(b[i],1,a[i],1);
                    break;//同真同假
                case 2:
                    TS.add_clause(a[i],1,b[i],0);
                    TS.add_clause(b[i],1,a[i],0);
                    break;//不能同真
            }
        }
    }
    int main(){
        // freopen("in.txt","r",stdin);
        scanf("%d",&t);
        while(t--){
            scanf("%d%d",&n,&m);
            for(int i=0;i<m;i++){
                scanf("%d%d%d",&a[i],&b[i],&c[i]);
            }
            int l=0,r=m;
            while(l<=r){
                int mid=(l+r)/2;
                build(mid);
                if(TS.solve()==true) l=mid+1;
                else r=mid-1;
            }
            printf("%d
    ",l-1);
        }
        return 0;
    }
  • 相关阅读:
    C# DateTimePicker控件详解
    python2.7虚拟环境virtualenv安装及使用
    Python2.7 安装numpy报错解决方法
    关于C语言中递归的一点点小问题
    Drozer--AndroidApp安全评估工具
    Android--native层so文件调试
    New Blog
    小旭讲解 LeetCode 53. Maximum Subarray 动态规划 分治策略
    2017年度回忆与总结 – 心态
    基于文本图形(ncurses)的文本搜索工具 ncgrep
  • 原文地址:https://www.cnblogs.com/wuwangchuxin0924/p/6445883.html
Copyright © 2011-2022 走看看