二分+2SAT zoj3422 Go Deeper

来源:互联网 发布:飞鸽软件下载 编辑:程序博客网 时间:2024/04/29 05:21

传送门:点击打开链接

题意:

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

然后告诉你a,b,c三个数组的值,x数组里的值只有0和1,c里只有0,1,2问最多会输出什么。

思路:我们二分最后输出的答案,然后每次check都去建边跑2SAT,看是否符合要求。

#include <map>#include <set>#include <cmath>#include <ctime>#include <stack>#include <queue>#include <cstdio>#include <cctype>#include <bitset>#include <string>#include <vector>#include <cstring>#include <iostream>#include <algorithm>#include <functional>#define fuck(x) cout<<"["<<x<<"]";#define FIN freopen("input.txt","r",stdin);#define FOUT freopen("output.txt","w+",stdout);//#pragma comment(linker, "/STACK:102400000,102400000")using namespace std;typedef long long LL;typedef pair<int, int> PII;const int MX = 1e3 + 5;const int INF = 0x3f3f3f3f;const int mod = 1e9 + 7;struct Edge {    int v, nxt;} E[100005];int Head[MX][2], erear;void edge_init() {    erear = 0;    memset(Head, -1, sizeof(Head));}void edge_add(int z, int u, int v) {    E[erear].v = v;    E[erear].nxt = Head[u][z];    Head[u][z] = erear++;}void edge_add(int u, int v) {    edge_add(0, u, v);    edge_add(1, v, u);}int Stack[MX], Belong[MX], vis[MX], ssz, bsz;void DFS(int u, int s) {    vis[u] = 1;    if(s) Belong[u] = s;    for(int i = Head[u][s > 0]; ~i; i = E[i].nxt) {        int v = E[i].v;        if(!vis[v]) DFS(v, s);    }    if(!s) Stack[++ssz] = u;}void tarjan(int n) {    ssz = bsz = 0;    for(int i = 1; i <= n; i++) vis[i] = 0;    for(int i = 1; i <= n; i++) {        if(!vis[i]) DFS(i, 0);    }    for(int i = 1; i <= n; i++) vis[i] = 0;    for(int i = ssz; i >= 1; i--) {        if(!vis[Stack[i]]) DFS(Stack[i], ++bsz);    }}int n, m;int A[10005], B[10005], C[10005];bool check(int x) {    edge_init();    for(int i = 1; i <= x; i++) {        int u = A[i], v = B[i]; u++; v++;        if(C[i] == 0) {            edge_add(u + n, v); edge_add(v + n, u);        }        if(C[i] == 1) {            edge_add(u + n, v + n); edge_add(u, v);            edge_add(v + n, u + n); edge_add(v, u);        }        if(C[i] == 2) {            edge_add(u, v + n); edge_add(v, u + n);        }    }    tarjan(2 * n);    for(int i = 1; i <= n; i++) {        if(Belong[i] == Belong[i + n]) return false;    }    return true;}int solve() {    int l = 1, r = ::m, m;    while(l <= r) {        m = (l + r) >> 1;        if(check(m)) l = m + 1;        else r = m - 1;    }    return l - 1;}int main() {    int T; //FIN;    scanf("%d", &T);    while(T--) {        scanf("%d%d", &n, &m);        for(int i = 1; i <= m; i++) {            scanf("%d%d%d", &A[i], &B[i], &C[i]);        }        printf("%d\n", solve());    }    return 0;}


0 0
原创粉丝点击