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‘->ax[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\n",r+1);
        else printf("%d\n",l+1);
    }
    return 0;
}

Go Deeper(2010成都现场赛题)(2-sat),布布扣,bubuko.com

时间: 2024-08-02 06:57:51

Go Deeper(2010成都现场赛题)(2-sat)的相关文章

Error Curves(2010成都现场赛题)

F - Error Curves Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Description Josephina is a clever girl and addicted to Machine Learning recently. She pays much attention to a method called Linear Discriminant Analysis, which h

hdu 4089 不错的DP 北京现场赛题

http://acm.hdu.edu.cn/showproblem.php?pid=4089 还有疑惑,需要重新推: 但是学到的: 1.A=a+b+c  abc是三种情况,那么P(A)=a*P(a->事件)+b*P(b->事件)+c*P(c->事件); a->事件意思是 在a情况下的事件,就是全概率公式的思想吧 2.一定注意每一步会不会出现分母为0 的情况,以及预处理的时候对于一些特殊情况导致自己的式子会出现分母为0的排除掉 3.概率DP经常出现推出了式子但是自己不会写代码的情况,

hdu 4465 Candy 2012 成都现场赛

1 /** 2 对于大数的很好的应用,,缩小放大,,保持精度 3 **/ 4 #include <iostream> 5 #include <cmath> 6 #include <algorithm> 7 #include <cstdio> 8 using namespace std; 9 10 int main() 11 { 12 double n,p; 13 int cnt =1; 14 while(cin>>n>>p){ 15

HDU-4464-Browsing History (2012 ACM/ICPC成都现场赛!)

Browsing History Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 3065    Accepted Submission(s): 1692 Problem Description One day when you are going to clear all your browsing history, you come

hdu 5074 DP 2014鞍山现场赛题

hdu 5074 http://acm.hdu.edu.cn/showproblem.php?pid=5074 挺水的DP,注意依a[i-1]和a[i]的正负区分状态转移,然后O(n^3)即可轻易解决,我DP挺弱的也能过,貌似也就CF C题水平 //#pragma comment(linker, "/STACK:102400000,102400000") #include <cstdio> #include <cstring> #include <algo

hdu 4810 思维题+二进制位规律+异或规律 213南京现场赛题

http://acm.hdu.edu.cn/showproblem.php?pid=4810 以前做过一些涉及异或的题,化为二进制形式,然后统计0,1个数是一种很常见的处理方法,但是在做这个题的时候居然没尝试,脑残啊...... 一开始看5s时限,感觉稍微暴力一点应该可以,于是YY的O(n^3)算法但是没去实现,明显超时啊,大致就是通过C(n,1)的组合可以在O(n^2)内处理出C(n,2)的组合,在通过C(n,2)处理出C(n,3)的组合....但是C(n,2)已经是n^2个数了,所以算法是O

HDU-4472-Count (2012 ACM/ICPC成都现场赛)

Count Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1850    Accepted Submission(s): 1200 Problem Description Prof. Tigris is the head of an archaeological team who is currently in charge of a

2012 ICPC/ACM 成都现场赛 Candy

题目来源: http://acm.hdu.edu.cn/showproblem.php?pid=4465 题意:输入m,p;从两个盒子里各有n颗糖,每天取一颗,发现其中一个盒子空,求另外一个盒子糖果数的期望.p,1-p为取糖概率: 分析: 给盒子编号 A,B , 设另外一个盒子(为B) 剩  n - k 个 , 则 在过去的 (n + k)次 有 k 次 取到B , 且当前这次取到A . 同理 对另外一个盒子为(A) . 则 期望的公式为: Σ( n - k) * C(n + k , k) *

hdu 5073 2014鞍山现场赛题 物理题

http://acm.hdu.edu.cn/showproblem.php?pid=5073 推公式即可,质心公式segma(xi*wi)/segma(wi) 最终剩下的一定是连续n-k个星 然后枚举左边需要移除几个星即可 计算I的时候展开来算 比较坑的地方在于,星星的位置如果是int型,一定记得Double计算的时候 *1.0或者直接将位置数组声明为double  否则WA到死... //#pragma comment(linker, "/STACK:102400000,102400000&q