HDU_4115_Eliminate the Conflict(2-SAT)

来源:互联网 发布:艾科特餐饮软件 编辑:程序博客网 时间:2024/06/08 07:15

Eliminate the Conflict

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2036    Accepted Submission(s): 880



Problem Description
Conflicts are everywhere in the world, from the young to the elderly, from families to countries. Conflicts cause quarrels, fights or even wars. How wonderful the world will be if all conflicts can be eliminated.
Edward contributes his lifetime to invent a 'Conflict Resolution Terminal' and he has finally succeeded. This magic item has the ability to eliminate all the conflicts. It works like this:
If any two people have conflict, they should simply put their hands into the 'Conflict Resolution Terminal' (which is simply a plastic tube). Then they play 'Rock, Paper and Scissors' in it. After they have decided what they will play, the tube should be opened and no one will have the chance to change. Finally, the winner have the right to rule and the loser should obey it. Conflict Eliminated!
But the game is not that fair, because people may be following some patterns when they play, and if the pattern is founded by others, the others will win definitely.
Alice and Bob always have conflicts with each other so they use the 'Conflict Resolution Terminal' a lot. Sadly for Bob, Alice found his pattern and can predict how Bob plays precisely. She is very kind that doesn't want to take advantage of that. So she tells Bob about it and they come up with a new way of eliminate the conflict:
They will play the 'Rock, Paper and Scissors' for N round. Bob will set up some restricts on Alice.
But the restrict can only be in the form of "you must play the same (or different) on the ith and jth rounds". If Alice loses in any round or break any of the rules she loses, otherwise she wins.
Will Alice have a chance to win?
 

Input
The first line contains an integer T(1 <= T <= 50), indicating the number of test cases.
Each test case contains several lines.
The first line contains two integers N,M(1 <= N <= 10000, 1 <= M <= 10000), representing how many round they will play and how many restricts are there for Alice.
The next line contains N integers B1,B2, ...,BN, where Bi represents what item Bob will play in the ith round. 1 represents Rock, 2 represents Paper, 3 represents Scissors.
The following M lines each contains three integers A,B,K(1 <= A,B <= N,K = 0 or 1) represent a restrict for Alice. If K equals 0, Alice must play the same on Ath and Bth round. If K equals 1, she must play different items on Ath and Bthround.
 

Output
For each test case in the input, print one line: "Case #X: Y", where X is the test case number (starting with 1) and Y is "yes" or "no" represents whether Alice has a chance to win.
 

Sample Input
23 31 1 11 2 11 3 12 3 15 51 2 3 2 11 2 11 3 11 4 11 5 12 3 0
 

Sample Output
Case #1: noCase #2: yes
Hint
'Rock, Paper and Scissors' is a game which played by two person. They should play Rock, Paper or Scissors by their hands at the same time. Rock defeats scissors, scissors defeats paper and paper defeats rock. If two people play the same item, the game is tied..
 

Source
2011 Asia ChengDu Regional Contest
 

题意:Alice和Bob在玩剪刀石头布,神奇的是Alice能够猜出Bob要出的手法,所以她总是会赢。现在对Alice给出M个限制(a, b, k),如果 k = 1,则代表在第a轮和b轮Alice必须用不同的手法;如果 k = 0,则代表第a轮和b轮Alice必须用相同的手法。如果Alice在某局中输了则输出 no,否则输出 yes。

分析:2-SAT问题。在某一轮中Alice要想不输,则有两种手法(a1, a2)可以使用;现在当 k = 1 ,那么在 a1 == b1的情况下会发生矛盾,所以连边 a1 -> b2,b1 -> a2;当 k = 0,那么则在a1 != b1 的情况下会发生矛盾,所以连边 a1 -> b2,b1 -> a2。

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4115

代码清单:

/******************************************************************************* *** problem ID  : EE.cpp *** create time : Sat Nov 14 12:20:01 2015 *** author name : nndxy *** author blog : http://blog.csdn.net/jhgkjhg_ugtdk77 *** author motto: never loose enthusiasm for life, life is to keep on fighting! *******************************************************************************/#include <map>#include <set>#include <cmath>#include <queue>#include <stack>#include <ctime>#include <vector>#include <cctype>#include <string>#include <cstdio>#include <cstring>#include <cstdlib>#include <iostream>#include <algorithm>#include <bits/stdc++.h>using namespace std;#define exit() return 0typedef long long ll;typedef unsigned int uint;typedef unsigned long long ull;const int maxn = 10000 + 5;const int maxm = 10000 + 5;int T, cases;int n, M;int B[maxn];struct X{ int u, v; } x[maxn];struct Q{ int a, b, k; } limit[maxm];int dfn[maxn * 2];int low[maxn * 2];vector <int> graph[maxn * 2];stack <int> sta;bool InStack[maxn * 2];int belong[maxn * 2];int sccno, idx;void init(){memset(dfn, 0, sizeof(dfn));memset(low, 0, sizeof(low));memset(InStack, false, sizeof(InStack));memset(belong, 0, sizeof(belong));for(int i = 1; i < 2 * maxn; i++) graph[i].clear();sccno = idx = 0;}void input(){scanf("%d%d", &n, &M);for(int i = 1; i <= n; i++){scanf("%d", &B[i]);if(B[i] == 1) { x[i].u = 1; x[i].v = 2; }else if(B[i] == 2) { x[i].u = 2; x[i].v = 3; }else { x[i].u = 3; x[i].v = 1; }}for(int i = 1; i <= M; i++){scanf("%d%d%d", &limit[i].a, &limit[i].b, &limit[i].k);}}void createGraph(){for(int i = 1; i <= M; i++){ int l = limit[i].a;int r = limit[i].b;if(limit[i].k == 1){if(x[l].u == x[r].u){graph[l].push_back(r + n);graph[r].push_back(l + n);}if(x[l].u == x[r].v){graph[l].push_back(r);graph[r + n].push_back(l + n);}if(x[l].v == x[r].u){graph[l + n].push_back(r  + n);graph[r].push_back(l);}if(x[l].v == x[r].v){graph[l + n].push_back(r);graph[r + n].push_back(l);}}else{if(x[l].u != x[r].u){graph[l].push_back(r + n);graph[r].push_back(l + n);}if(x[l].u != x[r].v){graph[l].push_back(r);graph[r + n].push_back(l + n);}if(x[l].v != x[r].u){graph[l + n].push_back(r  + n);graph[r].push_back(l);}if(x[l].v != x[r].v){graph[l + n].push_back(r);graph[r + n].push_back(l);}}}}void tarjan(int u){dfn[u] = low[u] = ++idx;InStack[u] = true; sta.push(u);for(int i = 0; i < graph[u].size(); i++){int v = graph[u][i];if(!dfn[v]){tarjan(v);low[u] = min(low[u], low[v]);}if(InStack[v]){low[u] = min(low[u], dfn[v]);}} if(low[u] == dfn[u]){sccno++;while(!sta.empty()){int j = sta.top(); sta.pop();InStack[j] = false;belong[j] = sccno;if(j == u) break;}}}void findscc(){for(int i = 1; i <= 2 * n; i++){if(!dfn[i]) tarjan(i);}}bool exitSolution(){for(int i = 1; i <= n; i++) if(belong[i] == belong[i + n]) return false;return true;}void solve(){printf("Case #%d: ", cases);createGraph();findscc();if(exitSolution()) puts("yes");else puts("no");}int main(){scanf("%d", &T);for(cases = 1; cases <= T; cases++){init();input();solve();}   exit();}


0 0