剪刀石头布

来源:互联网 发布:淘宝追加评价看不到 编辑:程序博客网 时间:2024/04/28 18:08
Problem Description
现有M
个人一起玩剪刀石头布,以1
-M
编号,每人出一种,出过不再改变,但是我们并不知道它到底是哪一种。 
(其中石头赢剪刀,剪刀赢布,布赢石
头,一样则平)
裁判用两种说法对这M
个人所构成的输赢关系进行描述: 
一:"1 A B",表示第A个人和第B个人出的一样。 
二:"2 A B",表示第A个人赢第B个人。 
裁判对M个人,用以上两种说法,连说N句话,其中有真的、也有假的。

一句话出现以下情况,就是假话,否则就是真话。 

1该句话与之前的某些真话冲突; 

2)该句话中A或B比M大; 
3)该句话表示A赢A。 
请根据给定的M和N,输出假话数。其中(1<= M<=10,000),(0<= N <= 10,000)

Input
第1行是一个自然数K,代表有K组数据。
每组数据以一个空行分隔,其中每组数据的第1行是两个自然数M、N,以空格分开。 
每组数据的第2行至N+1行,每行是三个自然数X,A,B,三个数之间用空格分开,X(1或2)表示说法的种类。
 
Output

每组数据对应一行,每行有一个整数,代表假话数。

sample input

3

43 11

1 4 3

2 3 3

1 4 1

1 4 4

2 3 3

1 2 2

2 1 4

1 1 1

2 1 4

2 3 4

2 3 2


66  9

2 3 1

2 4 4

2 1 2

2 4 3

2 4 2

2 2 3

1 3 2

1 2 1

1  1 1


6 7

2 3 7

2 1 2

2 4 4

1 2 1

1 3 2

1 2 3

2 1 3


sample output

4

3

建一个图,如果A win B, 则A 到 B的边权为1, 而B到A的边权为2;如果A draw B, 则A 到 B的边权为0, B到A的边权为0。 每次输入一句话则搜索两者是否边连通,如果不连通则加边;如果连通,则看两者的距离MOD 3的值, 如果MOD 3 得1则前者胜后者,得0则平,得2 则后者胜前者。比如说A胜B, B 胜 C, 则可知C胜A,那么A->B = 1, B->A = 2, B->C = 1, C->B = 2,那么可推出A->C = 2:A->B + B->C = 2 , 或者C->A = C->B + B->A = 4 mod 3 =1;同者都说明C win A。


#include<cstdio>#include<cstring>#include<algorithm>#include<queue>#include<stack>#include<vector>#include<cmath>#include<string>using namespace std;struct Edge{int v, next, f;}e[20000];int g[20000];int num;void addedge(int a, int b, int f){e[++num].v = b;e[num].next = g[a];e[num].f = f;g[a] = num;}int vis[10000];int dfs(int a, int b){int i, ret  = 0;;for(i = g[a]; i; i = e[i].next){int v = e[i].v;if(v == b)return e[i].f;if(vis[v]){vis[i] = 0;ret = dfs(v, b);vis[a] = 1;}if(ret >= 0)return e[i].f + ret;}return -1;}int main(){int n, m;int i, j, k;int cnt;int t;int a, b, q;scanf("%d", &t);while(t--){int bf = 0;cnt = 0;int flag = 0;scanf("%d%d", &m, &n);num = 0;for(int i = 0; i <= 2 * n; i++)e[i].f = -1;memset(g, 0, sizeof(g));memset(vis, 1, sizeof(vis));while(n--){scanf("%d%d%d", &q, &a, &b);if(q == 1){if(a == b)continue;vis[a] = 0;int dis = dfs(a, b);vis[a] = 1;if(dis == -1){addedge(a, b, 0);addedge(b, a, 0);}else if(dis % 3 != 0)cnt ++;}if(q == 2){if(a == b || a > m || b > m){cnt ++;continue;}vis[a] = 0;int dis = dfs(a, b) % 3;vis[a] = 1;if(dis != -1 && dis != 1)cnt ++;if(dis == -1){addedge(a, b, 1);addedge(b, a, 2);}}}printf("%d\n", cnt);}    return 0;}


0 0
原创粉丝点击