HDU 3715 二分+2-SAT

Go Deeper
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

题意:找到最大的deep。

思路:二分答案,根据矛盾关系建图,判断是否符合要求。

代码:

#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<math.h>
#include<string.h>
using namespace std;
const int maxn=30000;
const int maxm=9000000;
int head[maxn],low[maxn],dfn[maxn],tol,Stack[maxn],instack[maxn],belong[maxn],indexx,scc,top,n,a[maxn],b[maxn],c[maxn];
struct node
{
        int to,next;
}edge[maxm];
void add(int u,int v)
{
        edge[tol].next=head[u];
        edge[tol].to=v;
        head[u]=tol++;
}
void tarjin(int u)
{
        low[u]=dfn[u]=++indexx;
        Stack[top++]=u;instack[u]=1;
        int i,v;
        for(i=head[u];i!=-1;i=edge[i].next)
        {
                v=edge[i].to;
                if(!dfn[v])
                {
                        tarjin(v);
                        if(low[u]>low[v])low[u]=low[v];
                }
                else if(instack[v]&&low[u]>dfn[v])low[u]=dfn[v];
        }
        if(low[u]==dfn[u])
        {
                scc++;
                do
                {
                        v=Stack[--top];
                        instack[v]=0;
                        belong[v]=scc;
                }while(u!=v);
        }
}

int solve(int mid)
{
        memset(head,-1,sizeof(head));tol=0;
        int i,j;
        for(i=1;i<=mid;i++)
        {
                if(c[i]==0)
                {
                        add(2*a[i],2*b[i]+1);
                        add(2*b[i],2*a[i]+1);
                }
                else if(c[i]==1)
                {
                        add(2*a[i],2*b[i]);
                        add(2*b[i],2*a[i]);
                        add(2*a[i]+1,2*b[i]+1);
                        add(2*b[i]+1,2*a[i]+1);
                }
                else
                {
                        add(2*a[i]+1,2*b[i]);
                        add(2*b[i]+1,2*a[i]);
                }
        }
        memset(instack,0,sizeof(instack));
        memset(dfn,0,sizeof(dfn));
        scc=indexx=top=0;
        memset(belong,0,sizeof(belong));
        for(i=0;i<2*n;i++)if(!dfn[i])tarjin(i);
        for(i=0;i<n;i++)if(belong[2*i]==belong[2*i+1])return 0;
        return 1;
}
int main()
{
        int i,j,k,m,T;
        scanf("%d",&T);
        while(T--)
        {
              scanf("%d%d",&n,&m);
              for(i=1;i<=m;i++)scanf("%d%d%d",&a[i],&b[i],&c[i]);
              int left=1,right=m,mid;
              while(left<right)
              {
                      mid=(left+right+1)>>1;
                      if(solve(mid))left=mid;
                      else right=mid-1;
              }
             // while(solve(left))left++;
              printf("%d\n",left);
        }
        return 0;
}


 

posted @ 2013-09-05 00:01  线性无关  阅读(113)  评论(0)    收藏  举报