2019 11/11 欢乐的爆零赛 T1 变换游戏 题解

题目大意

对于两个玩家,当轮到一方操作时,他必须选一个点(该点不能为根),要求该点与其父亲节点的边权为1,然后将该点到根路径上的所有边权变反(0变1,1变0)
当某方无法进行操作时,对方获胜。
给定一颗节点数为n的树(边长均为0或1),对其进行两种操作:
①输入1,x,y,z 将连接x,y的边长更新为z。
②输入0,x 将该树以x为根询问先手必胜或后手必胜。
先手胜输出boss,后手胜输出wang。

对于100%的数据,n,m<=30000

样例 1
2 3
1 2 0
0 1
1 2 1 1
0 2

wang
boss

样例2
4 11
1 2 1
2 3 1
3 4 0
0 1
0 2
0 3
0 4
1 2 1 0
0 1
0 2
0 3
1 3 4 1
0 3
0 4

boss
wang
boss
wang
wang
boss
boss
wang
boss

在这里插入图片描述如图,对每次的根节点,由于最终每条边的边权均为0时游戏结束,所以我们只需要考虑根节点的每个长子即可。
观察样例可显然得出,当根节点与其长子的边权为1时,一定需要奇数步将1最终变为0.(如1直接变为0,或1变为0再变为1再变为0…)
同理,若边权为0,一定需要偶数步将0最终变为0.

那么每次遍历与根节点直接相连的边即可。

附代码

#include<stdio.h>
#include<bits/stdc++.h>
#define maxn 30005
using namespace std;

char buf[1<<20],*p1,*p2;
#define GC (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<20,stdin),p1==p2)?0:*p1++)
inline int read()
{
    char t=GC;
    int x=0;
    while(!isdigit(t)) t=GC;
    while(isdigit(t)) x=x*10+t-48,t=GC;
    return x;
}
int n,m,cnt;
int elast[maxn],len[maxn*2],ey[maxn*2],ne[maxn*2];
void add_edge(int x,int y,int z){
	cnt++;
	ey[cnt]=y;
	len[cnt]=z;
	ne[cnt]=elast[x];
	elast[x]=cnt;
}
int main(){
//	freopen("change.in","r",stdin);
//	freopen("change.out","w",stdout);
	scanf("%d%d",&n,&m);
	for(int i=1;i<n;i++){
		int x,y,z;
		scanf("%d%d%d",&x,&y,&z);
		add_edge(x,y,z);
		add_edge(y,x,z);
	}
	for(int i=1;i<=m;i++){
		int c;
		scanf("%d",&c);
		if(c){
			int x,y,z;
			scanf("%d%d%d",&x,&y,&z);
			for(int j=elast[x];j;j=ne[j]){
				int v=ey[j];
				if(v==y){
					len[j]=z;
					break;
				}
			}
			for(int j=elast[y];j;j=ne[j]){
				int v=ey[j];
				if(v==x){
					len[j]=z;
					break;
				}
			}
			continue;
		}
		else{
			int root;
			scanf("%d",&root);
			int Ans=1;
			for(int i=elast[root];i;i=ne[i]){
				Ans^=len[i];
			}
			if(!Ans) printf("boss\n");
			else printf("wang\n");
			continue;
		}
	}
	return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值