HDU 4115 Eliminate the Conflict(2-sat)

来源:互联网 发布:php java混合 编辑:程序博客网 时间:2024/04/30 04:21

HDU 4115 Eliminate the Conflict

题目链接

题意:Alice和Bob这对狗男女在玩剪刀石头布,已知Bob每轮要出什么,然后Bob给Alice一些限制,1表示i轮和j轮Alice必须出不一样的,0表示必须出一样的,如果Alice有一局输了就算输了,否则就是赢,问Alice是否能赢

思路:2-sat问题,已经Bob出什么,Alice要么就出赢的要么就出平的,然后加上m个约束就是2-sat问题了

代码:

#include <cstdio>#include <cstring>#include <vector>using namespace std;const int N = 10005;int t, n, m, x[N], sn, S[N * 2];vector<int> g[N * 2];bool mark[N * 2];void init() {for (int i = 0; i < 2 * n; i++) g[i].clear();memset(mark, false, sizeof(mark));}void add_edge(int u, int x, int v, int y) {u = u * 2 + x;v = v * 2 + y;g[u^1].push_back(v);g[v^1].push_back(u);}bool dfs(int u) {if (mark[u^1]) return false;if (mark[u]) return true;mark[u] = true;S[sn++] = u;for (int i = 0; i < g[u].size(); i++) {int v = g[u][i];if (!dfs(v)) return false;}return true;}bool solve() {for (int i = 0; i < 2 * n; i += 2) {if (!mark[i] && !mark[i + 1]) {sn = 0;if (!dfs(i)) {for (int j = 0; j < sn; j++) mark[S[j]] = false;sn = 0;if (!dfs(i + 1)) return false;}}}return true;}int main() {int cas = 0;scanf("%d", &t);while (t--) {init();scanf("%d%d", &n, &m);int tmp;for (int i = 0; i < n; i++)scanf("%d", &x[i]);int u, v, w;while (m--) {scanf("%d%d%d", &u, &v, &w);u--; v--;int tmp = 6 - x[u] - x[v];int a = 6 - x[u] - tmp;int b = 6 - x[v] - tmp;int u1, u2, v1, v2;u2 = a > tmp; u1 = !u2;v2 = b > tmp; v1 = !v2;if (w == 1) {if (x[u] == x[v]) {add_edge(u, 1, v, 1);add_edge(u, 0, v, 0);} else add_edge(u, !u1, v, !v1);} else {if (x[u] == x[v]) {add_edge(u, 0, v, 1);add_edge(u, 1, u, 0);} else {add_edge(u, u1, u, u1);add_edge(v, v1, v, v1);}}}printf("Case #%d: %s\n", ++cas, solve() ? "yes" : "no");}return 0;}


1 0
原创粉丝点击