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

2 3 3 1 1 1 1 2 1 1 3 1 2 3 1 5 5 1 2 3 2 1 1 2 1 1 3 1 1 4 1 1 5 1 2 3 0

Sample Output

Case #1: no Case #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..

题意:

A和B两个人要用 N局“石头布剪刀”的游戏来决定胜负,现在给出A在每一轮游戏选择的手势(1表示石头,2表示布,3表示剪刀)。另外A给B设置了M个如a b k的限制,当k = 0时,要求B在第a局游戏和第b局游戏出的手势必须一样;当 k = 1时,要求B在第a局游戏和第b局游戏出的手势不能一样。对于B来说,输掉任意一局 或者 违反规则都是他输,反之他赢。这也就意味着在A和B全平局(每局出的手势一样)的情况下,是B赢。问你B有没有机会获胜。

分析:

因为Alice已经知道Bob的所有出拳,所以用a[maxn][2]数组保存那些出拳的结果。然后对于下面的要求作出Alice在第i轮选0还是选1的推断即可。看看是否有方法满足本2-SAT的n个解。

因为Alice一次都不能输,所以根据Bob出的拳,Alice只可以赢或者平局,即每次有两种选择,是2-SAT模型

然后会有一些矛盾对,假设第a次可以出a1,a2, 第b次可以出b1和b2

如果第a次和b次要求相同, 但是a1和b1不同,说明这个矛盾,建立连接 a1—>b2, b1—>a2.(a1与b1不同时最多有4种可能的情况需要考虑)

同理,第a次和b次要求不相同,但是a1和b2相同,说明这个矛盾,建立链接a1—>b1,  b2—>a2

……

然后用2-SAT判断即可.

#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
#include <stack>
#include <algorithm>
#define MAXN 60000+100
#define MAXM 200000+10
#define INF 100000000
using namespace std;
struct Edge
{
int from, to, next;
};
Edge edge[MAXM];
int head[MAXN], edgenum;
int low[MAXN], dfn[MAXN];
int dfs_clock;
int sccno[MAXN], scc_cnt;
stack<int> S;
bool Instack[MAXN];
int N, M;//N局游戏 M个限制
int TT = 1;
void init()
{
edgenum = 0;
memset(head, -1, sizeof(head));
}
void addEdge(int u, int v)
{
Edge E = {u, v, head[u]};
edge[edgenum] = E;
head[u] = edgenum++;
}
void getMap()
{
int a, b, k;
for(int i = 1; i <= N; i++)
{
scanf("%d", &k);
switch(k)
{
//对手出石头
case 1: //在第i局出布 或者 出石头
addEdge(i + 4 * N, i);//不出布 就必须出石头
addEdge(i + 3 * N, i + N);//不出石头 就必须出布
break;
//对手出布
case 2: //在第i局出剪刀 或者 出布
addEdge(i + 5 * N, i + N);//不出剪刀 就必须出布
addEdge(i + 4 * N, i + 2 * N);//不出布 就必须出剪刀
break;
//对手出剪刀
case 3: //在第i局出石头 或者 出剪刀
addEdge(i + 3 * N, i + 2 * N);//不出石头 就必须出剪刀
addEdge(i + 5 * N, i);//不出剪刀 就必须出石头
break;
}
}
//每局只能出一个
for(int i = 1; i <= N; i++)
{
//出了石头就不能出其他的
addEdge(i, i + 4 * N);
addEdge(i, i + 5 * N);
//出了布 就不能出其他的
addEdge(i + N, i + 3 * N);
addEdge(i + N, i + 5 * N);
//出了剪刀 就不能出其他的
addEdge(i + 2 * N, i + 3 * N);
addEdge(i + 2 * N, i + 4 * N);
}
while(M--)
{
scanf("%d%d%d", &a, &b, &k);
if(k == 1)//a局和b局不同
{
addEdge(a, b + 3 * N);//a局出石头 b局一定不能出石头
addEdge(b, a + 3 * N);//b局出石头 a局一定不能出石头
addEdge(a + N, b + 4 * N);//a局出布 b局一定不能出布
addEdge(b + N, a + 4 * N);//a局出布 b局一定不能出布
addEdge(a + 2 * N, b + 5 * N);//a局出剪刀 b局一定不能出剪刀
addEdge(b + 2 * N, a + 5 * N);//b局出剪刀 a局一定不能出剪刀
}
else//a局和b局一样
{
addEdge(a, b);//a局出石头 b局也出石头
addEdge(b, a);//b局出石头 a局也出石头
addEdge(a + N, b + N);//a局出布 b局也出布
addEdge(b + N, a + N);//b局出布 a局也出布
addEdge(a + 2 * N, b + 2 * N);//a局出剪刀 b局也出剪刀
addEdge(b + 2 * N, a + 2 * N);//b局出剪刀 a局也出剪刀
}
}
}
void tarjan(int u, int fa)
{
int v;
low[u] = dfn[u] = ++dfs_clock;
S.push(u);
Instack[u] = true;
for(int i = head[u]; i != -1; i = edge[i].next)
{
v = edge[i].to;
if(!dfn[v])
{
tarjan(v, u);
low[u] = min(low[u], low[v]);
}
else if(Instack[v])
low[u] = min(low[u], dfn[v]);
}
if(low[u] == dfn[u])
{
scc_cnt++;
for(;;)
{
v = S.top(); S.pop();
Instack[v] = false;
sccno[v] = scc_cnt;
if(v == u) break;
}
}
}
void find_cut(int l, int r)
{
memset(low, 0, sizeof(low));
memset(dfn, 0, sizeof(dfn));
memset(sccno, 0, sizeof(sccno));
memset(Instack, false, sizeof(Instack));
dfs_clock = scc_cnt = 0;
for(int i = l; i <= r; i++)
if(!dfn[i]) tarjan(i, -1);
}
void solve()
{
printf("Case #%d: ", TT++);
for(int i = 1; i <= 3 * N; i++)
{
if(sccno[i] == sccno[i + 3 * N])
{
printf("no\n");
return ;
}
}
printf("yes\n");
}
int main()
{
int t;
scanf("%d", &t);
while(t--)
{
scanf("%d%d", &N, &M);
init();
getMap();
find_cut(1, 6 * N);
solve();
}
return 0;
}

图论--2-SAT--HDU/HDOJ 4115 Eliminate the Conflict的更多相关文章

  1. HDU 4115 Eliminate the Conflict(2-sat)

    HDU 4115 Eliminate the Conflict pid=4115">题目链接 题意:Alice和Bob这对狗男女在玩剪刀石头布.已知Bob每轮要出什么,然后Bob给Al ...

  2. hdu 4115 Eliminate the Conflict ( 2-sat )

    Eliminate the Conflict Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/O ...

  3. HDU 4115 Eliminate the Conflict(2-SAT)(2011 Asia ChengDu Regional Contest)

    Problem Description Conflicts are everywhere in the world, from the young to the elderly, from famil ...

  4. 图论--差分约束--HDU\HDOJ 4109 Instrction Arrangement

    Problem Description Ali has taken the Computer Organization and Architecture course this term. He le ...

  5. HDU 4115 Eliminate the Conflict

    2-SAT,拆成六个点. #include<cstdio> #include<cstring> #include<cmath> #include<stack& ...

  6. hdu4115 Eliminate the Conflict

    Eliminate the Conflict Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Othe ...

  7. Eliminate the Conflict HDU - 4115(2-sat 建图 hhh)

    题意: 石头剪刀布 分别为1.2.3,有n轮,给出了小A这n轮出什么,然后m行,每行三个数a b k,如果k为0 表示小B必须在第a轮和第b轮的策略一样,如果k为1 表示小B在第a轮和第b轮的策略不一 ...

  8. 图论问题(2) : hdu 1102

    题目转自hdu 1102,题目传送门 题目大意: 输入一个n*n的邻接矩阵,其中i行j列代表从i到j的路径的长度 然后又m条路已经帮你修好了,求最短要修多长的路才能使所有村庄连接 不难看出,这道题就是 ...

  9. HDU/HDOJ 2612 Find a way 双向BFS

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2612 思路:从两个起点出发,有多个终点,求从两个起点同时能到达的终点具有的最小时间,开两个数组分别保存 ...

随机推荐

  1. wireshark抓包实战(六),过滤器

    目录 一.抓包过滤器 1.语法来源 2.语法 二.显示过滤器 1.语法来源 2.关键要素 wireshark中,过滤器有两种,一种是抓包过滤器,一种是显示过滤器! 抓包过滤器适合大网络环境,配置与抓包 ...

  2. Java第二十一天,集合三大接口Set、List、Map的新方法——of方法

    of public static List<E> of(E.....e) 这是jdk 9推出的一个针对于Set,List,Map三大集合接口的新方法. 注意: 是静态方法. 只适用于Set ...

  3. Golang Web入门(1):自顶向下理解Http服务器

    摘要 由于Golang优秀的并发处理,很多公司使用Golang编写微服务.对于Golang来说,只需要短短几行代码就可以实现一个简单的Http服务器.加上Golang的协程,这个服务器可以拥有极高的性 ...

  4. Python进度条模块tqdm实现任务进度可视化

    一.前言 tqdm 是一个易用性强.扩展性高的 Python 进度条库,可以在 Python 长循环中添加一个进度提示信息,我们只需要封装任意的迭代器 tqdm(iterator) 即可. 二.安装 ...

  5. JUC——检视阅读

    JUC--检视阅读 参考资料 JUC知识图参考 JUC框架学习顺序参考 J.U.C学习总结参考,简洁直观 易百并发编程,实践操作1,不推荐阅读,不及格 JUC文章,带例子讲解,可以学习2 Doug L ...

  6. CH5501 环路运输(单调栈)

    传送门 思路: 遇到一个环,用正常人类的思想就先把环从中间截断然后将其补成2*n长度的链.环上的最小距离换到链上就是i以n/2为半径范围内的点(画图肉眼可见).由于两个点是等价的,所以我们考虑有序对( ...

  7. Golang中的Gosched、Goexit、GOMAXPROCS

    Golang进程权限调度包runtime三大函数Gosched,Goexit,GOMaXPROCS runtime.Gosched(),用于让出CPU时间片,让出当前goroutine的执行权限,调度 ...

  8. mysql截取函数常用方法 即mysql 字符串 截取-- - 最后带上java字符串截取规则比较

    常用的mysql截取函数有:left(), right(), substring(), substring_index() 下面来一一说明一下: 1.左截取left(str, length) 说明:l ...

  9. 如何实现Jenkins 编译结果通知到QQ好友及QQ群组<很遗憾 2019年1月1日腾讯停止了webqq机器人的服务支持>

    Jenkins-NotifyQQ NotifyQQ 运行于Docker 本文介绍mac 环境下实现Jenkins编译结果QQ即时通知 Jenkins 安装使用及iOS自动化打包,邮件通知请参考本人博客 ...

  10. 练习,自定义TextView(1.1)

    重新自定义TextView是非常有趣的事情,跟着Android4高级编程,通过自定义TextView,来敲一下代码: 这个是那么的简单,自定义TextView,新建CustomTextView继承Te ...