hdu3715 Go Deeper

来源:互联网 发布:宝宝秀软件下载 编辑:程序博客网 时间:2024/04/29 13:31

要求输出可能达到的最大值,显然二分

x数组只能为0或1,可以联想到twosat 

只有当 x[a[dep]] + x[b[dep]] != c[dep]时候才能进入下一层   则可以根据这个条件加限制

c == 0时   a  b 不能同时为0

c == 1时   a  b 必须相等

c == 2时   a  b 不能同时为1


//#pragma warning (disable: 4786)//#pragma comment (linker, "/STACK:16777216")//HEAD#include <cstdio>#include <ctime>#include <cstdlib>#include <cstring>#include <queue>#include <string>#include <set>#include <stack>#include <map>#include <cmath>#include <vector>#include <iostream>#include <algorithm>using namespace std;//LOOP#define FF(i, a, b) for(int i = (a); i < (b); ++i)#define FD(i, b, a) for(int i = (b) - 1; i >= (a); --i)#define FE(i, a, b) for(int i = (a); i <= (b); ++i)#define FED(i, b, a) for(int i = (b); i>= (a); --i)#define REP(i, N) for(int i = 0; i < (N); ++i)#define CLR(A,value) memset(A,value,sizeof(A))#define CPY(a, b) memcpy(a, b, sizeof(a))#define FC(it, c) for(__typeof((c).begin()) it = (c).begin(); it != (c).end(); it++)//STL#define SZ(V) (int)V.size()#define PB push_back#define EQ(a, b) (fabs((a) - (b)) <= 1e-10)#define ALL(c) (c).begin(), (c).end()//INPUT#define RI(n) scanf("%d", &n)#define RII(n, m) scanf("%d%d", &n, &m)#define RIII(n, m, k) scanf("%d%d%d", &n, &m, &k)#define RIV(n, m, k, p) scanf("%d%d%d%d", &n, &m, &k, &p)#define RV(n, m, k, p, q) scanf("%d%d%d%d%d", &n, &m, &k, &p, &q)#define RS(s) scanf("%s", s)//OUTPUT#define WI(n) printf("%d\n", n)#define WS(s) printf("%s\n", s)typedef long long LL;typedef unsigned long long ULL;typedef vector <int> VI;const int INF = 100000000;const double eps = 1e-10;const int maxn = 250;int n, m;int a[10100], b[10100], c[10100];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 xval, int y, int yval)    {        x = x * 2 + xval;        y = y * 2 + yval;        G[x ^ 1].push_back(y);        G[y ^ 1].push_back(x);    }    bool solve()    {        for (int i = 0; i < n * 2; 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;    }};TwoSAT sat;bool test(int x){    sat.init(n);    REP(i, x)    {        if (c[i] == 0)            sat.add_clause(a[i], 1, b[i], 1);        else if (c[i] == 1)        {//            if (a[i] != b[i])//            {                sat.add_clause(a[i], 1, b[i], 0);                sat.add_clause(a[i], 0, b[i], 1);//            }        }        else if (c[i] == 2)            sat.add_clause(a[i], 0, b[i], 0);    }    return sat.solve();}void solve(){    int L = 0, R = m;    while (L <= R)    {        int mid = (L + R) >> 1;        if (test(mid))  L = mid + 1;        else    R = mid - 1;    }//    test(R);//    for (int i = 0; i < 2 * n; i += 2)//    {//        if (sat.mark[i])//            cout << 0 << ' ';//        else//            cout << 1 << ' ';//    }//    cout << endl;    printf("%d\n", R);}int main(){    int T;    RI(T);    while (T--)    {        RII(n, m);        REP(i, m)            RIII(a[i], b[i], c[i]);        solve();    }}


原创粉丝点击