HDU 3715 Go Deeper

二分答案 + 2-SAT判断

#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
#include<algorithm>
using namespace std;

const int maxn=8000+5;
int M,N,T;
int ans;
int L,R,Mid;
int a[10010],b[10010],c[10010];

struct TwoSAT
{
    int n;
    vector<int> G[maxn*2];
    bool mark[maxn*2];
    int S[maxn*2],c;

    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<n*2;i++) G[i].clear();
        memset(mark,0,sizeof mark);
    }

    void add_clause(int x,int y)
    {
        G[x].push_back(y^1);
        G[y].push_back(x^1);
    }

    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;
    }
};

int main()
{
    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]);
        L=0,R=M;

        while(L<=R)
        {
            Mid=(L+R)/2;
            TwoSAT T; T.init(N);
            for(int i=0;i<Mid;i++)
            {
                if(c[i]==2)
                {
                    T.add_clause(2*a[i]+1,2*b[i]+1);
                }
                else if(c[i]==1)
                {
                    T.add_clause(2*a[i]+1,2*b[i]);
                    T.add_clause(2*a[i],2*b[i]+1);
                }
                else if(c[i]==0)
                {
                    T.add_clause(2*a[i],2*b[i]);
                }
            }
            if(T.solve())
            {
                ans=Mid;
                L=Mid+1;
            }
            else R=Mid-1;
        }
        printf("%d\n",ans);
    }
    return 0;
}
时间: 2024-10-09 17:01:18

HDU 3715 Go Deeper的相关文章

HDU 3715 Go Deeper(2-sat)

HDU 3715 Go Deeper 题目链接 题意:根据题意那个函数,构造x数组,问最大能递归层数 思路:转化为2-sat问题,由于x只能是0,1,c只能是0,1,2那么问题就好办了,对于0, 1, 2对应分别是3种表达式,然后二分深度,搞2-sat即可 代码: #include <cstdio> #include <cstring> #include <cstdlib> #include <vector> #include <algorithm&g

hdu 3715 hdu 1816 hdu 4115 (2-sat)

三个2-sat问题,我总结一下自己的经验,我还是太菜,好久没做2-sat,又不太会建图了 总结:2-sat问题的核心就是建模 建模的思想很重要: 1.首先要怎么才能看出来是2-sat问题,对于每一个点,都有两种选择,则可以考虑是2-sat 比如让你在n组里面选n个,每组2个东西,这样就是2-sat的模型 2.确定是2-sat问题之后,就是要确定,拥有两种选择的对象,比如下面的例题里,有的是x[i]的取值有0或者1两种,有的是一串钥匙有两个,但你只能选择其中一个,则对于一个钥匙,它的取值有取或者不

HDU - 1816 Get Luffy Out *(二分 + 2-SAT)

题目大意:有N串钥匙,M对锁.每串钥匙只能选择其中一把,如何选择,才能使开的锁达到最大(锁只能按顺序一对一对开,只要开了其中一个锁即可) 解题思路:这题跟HDU - 3715 Go Deeper 这题的限制比较简单,都是二选一,2-SAT的裸题,只不过加了二分而已 附上HDU - 3715 Go Deeper题解 #include <cstdio> #include <cstring> #include <algorithm> #include <vector&g

【图论】2-sat总结

2-sat总结 2-sat问题,一般表现的形式为.每一个点有两种方式a,b,要么选a,要么选b.而且点点之间有一些约束关系.比如:u和v至少一个选a.那么这就是一个表达式.把a当成真,b当成假,那就是u真或v真.2-sat的题目就是这样.给定这些约束,推断是否会矛盾 注意表达式的转化形式,(事实上就是离散数学中那几种转换方式) 比方(u真且v真)或(u假且v假)就能够转化成(u真或v假)且(u假或v真),这样就能建立关系 2-sat中的原理,事实上和2染色是一样的,把每一个结点拆分成一个真结点和

【图论】

2-sat总结 2-sat问题,一般表现的形式为,每个点有两种方式a,b,要么选a,要么选b,并且点点之间有一些约束关系,例如:u和v至少一个选a,那么这就是一个表达式,把a当成真,b当成假,那就是u真或v真,2-sat的题目就是这样,给定这些约束,判断是否会矛盾 注意表达式的转化形式,(其实就是离散数学中那几种转换方式) 比如(u真且v真)或(u假且v假)就可以转化成(u真或v假)且(u假或v真),这样就能建立关系 2-sat中的原理,其实和2染色是一样的,把每个结点拆分成一个真结点和一个假结

2-SAT问题

2-SAT问题 现有一个由N个布尔值组成的序列A,给出一些限制关系,比如A[x]AND A[y]=0.A[x] OR A[y] OR A[z]=1等,要确定A[0..N-1]的值,使得其满足所有限制关系.这个称为SAT问题,特别的,若每种限制关系中最多只对两个元素进行限制,则称为2-SAT问题. 由于在2-SAT问题中,最多只对两个元素进行限制,所以可能的限制关系共有11种: A[x] NOT A[x] A[x] AND A[y] A[x] AND NOT A[y] A[x] OR A[y] A

图论 500题——主要为hdu/poj/zoj

转自——http://blog.csdn.net/qwe20060514/article/details/8112550 =============================以下是最小生成树+并查集======================================[HDU]1213   How Many Tables   基础并查集★1272   小希的迷宫   基础并查集★1325&&poj1308  Is It A Tree?   基础并查集★1856   More i

hdu图论题目分类

=============================以下是最小生成树+并查集====================================== [HDU] 1213 How Many Tables 基础并查集★ 1272 小希的迷宫 基础并查集★ 1325&&poj1308 Is It A Tree? 基础并查集★ 1856 More is better 基础并查集★ 1102 Constructing Roads 基础最小生成树★ 1232 畅通工程 基础并查集★ 123

题单二:图论500

http://wenku.baidu.com/link?url=gETLFsWcgddEDRZ334EJOS7qCTab94qw5cor8Es0LINVaGMSgc9nIV-utRIDh--2UwRLvsvJ5tXFjbdpzbjygEdpGehim1i5BfzYgYWxJmu ==========  以下是最小生成树+并查集=========================[HDU]1213         How Many Tables        基础并查集★1272         小