HDU - 3715 Go Deeper (二分 + 2-SAT)

来源:互联网 发布:尚学堂java视频教程 编辑:程序博客网 时间:2024/05/20 02:27

题目大意:给出一个递归函数,问这个递归函数最多能递归几层

解题思路:二分枚举递归层数,然后依此建边

如果给出的c[i]为0时,那么x[a[i]]和x[b[i]]中的其中一个要为真,连边即为 !a[i]->b[i], !b[i] -> a[i]

如果给出的c[i]为1时,那么x[a[i]]和x[b[i]]两个要么都为真,要么都为假,连边即为a[i]->b[i], b[i]->a[i], !a[i]->!b[i], !b[i]->!a[i]

如果给出的c[i]为2时,那么x[a[i]]和x[b[i]]两个中的一个要为假
,连边即为a[i]->!b[i], b[i]->!a[i]

#include <cstdio>#include <cstring>#include <vector>using namespace std;#define N 10010#define M 410struct Node {    int a, b, c;}node[N];vector<int> G[M];bool mark[M];int S[M];int n, m, top;void init() {    scanf("%d%d", &n, &m);    for (int i = 1; i <= m; i++) {        scanf("%d%d%d", &node[i].a, &node[i].b, &node[i].c);    }}bool dfs(int u) {    if (mark[u ^ 1])        return false;    if (mark[u])        return true;    mark[u] = true;    S[++top] = u;    for (int i = 0; i < G[u].size(); i++)        if (!dfs(G[u][i]))            return false;    return true;}void AddEdge(int x, int valx, int y, int valy) {    G[2 * x + valx].push_back(y * 2 + valy);}bool judge(int mid) {    for (int i = 0; i < 2 * n; i++)        G[i].clear();    for (int i = 1; i <= mid; i++) {        if (node[i].c == 0) {            AddEdge(node[i].a, 0, node[i].b, 1);            AddEdge(node[i].b, 0, node[i].a, 1);        }        else if (node[i].c == 1) {            AddEdge(node[i].a, 0, node[i].b, 0);            AddEdge(node[i].b, 0, node[i].a, 0);            AddEdge(node[i].a, 1, node[i].b, 1);            AddEdge(node[i].b, 1, node[i].a, 1);        }        else if (node[i].c == 2) {            AddEdge(node[i].a, 1, node[i].b, 0);            AddEdge(node[i].b, 1, node[i].a, 0);        }    }    memset(mark, 0, sizeof(mark));    for (int i = 0; i < 2 * n; i += 2) {        if (!mark[i] && !mark[i ^ 1]) {            top = 0;            if (!dfs(i)) {                while (top) mark[S[top--]] = false;                if (!dfs(i ^ 1))                    return false;            }        }    }    return true;}void solve() {    int l = 1, r = m, mid;    while (l <= r) {        mid = (l + r) / 2;        if (judge(mid))            l = mid + 1;        else            r = mid - 1;    }    printf("%d\n", l - 1);}int main() {    int test;    scanf("%d", &test);    while (test--) {        init();        solve();    }    return 0;}
0 0
原创粉丝点击