HDU - 5963 朋友 思维 + 博弈

题意:中文题。

思路:考虑和根相连的一条树链,如果这条树链上和根相连的那条边权值为1,那么最终在该链上的操作次数要为奇数次才能使得和根相连的边的权值变为0(因为不论选择该条树链上哪个点,此边的权值总会翻转),同理可得和根相连的边若初始权值为0要操作偶数次。而无论两个人怎么操作,都不会改变这些根的直连边变0所需操作次数的奇偶性,而若总操作次数为奇数次的话那就必定是先手胜了,因此我们只需维护一个每个点的直连边中权值为1的个数就行了。

代码:

#include
#define ll long long
#define MAXN 50010
#define inf 0x3f3f3f3f
using namespace std;
typedef pair P;
map edge;
int degree[MAXN];
int main()
{
	int T, n, m, u, v, w, op;
	cin >> T;
	while(T--)
	{
		scanf("%d %d", &n, &m);
		memset(degree, 0, sizeof(degree));
		edge.clear();
		for(int i = 1; i < n; i++)
		{
			scanf("%d %d %d", &u, &v, &w);
			degree[u] += w;
			degree[v] += w;
			if(u > v) swap(u, v);
			edge[P(u, v)] = w;
		}
		while(m--)
		{
			scanf("%d", &op);
			if(op) {
				scanf("%d %d %d", &u, &v, &w);
				if(u > v) swap(u, v);
				degree[u] -= edge[P(u, v)];
				degree[v] -= edge[P(u, v)];
				degree[u] += w; degree[v] += w;
				edge[P(u, v)] = w;
			} else {
				scanf("%d", &u);
				if(degree[u] & 1) puts("Girls win!");
				else puts("Boys win!");
			}
		}
	}
    return 0;
}


你可能感兴趣的:(hdu,各种思维题,博弈论)