zoukankan      html  css  js  c++  java
  • [HDU5963]朋友

    [HDU5963]朋友

    题目大意:

    给定一棵(n(nle40000))个点的树,边权只能是(0)(1)。一局游戏开始时,会确定一个结点作为根。AB轮流操作。当一方操作时,他们需要先选择一个不为根的点,满足该点到其父亲的边权为1; 然后找出这个点到根节点的简单路径,将路径上所有边的权值翻转。当一方无法操作时(即所有边的边权均为0),另一方就获得了胜利。

    (m(mle40000))次操作,操作分为以下两种:

    1. 询问对于当前的树,如果以(x)为根节点开始游戏,哪方会获得胜利。
    2. (x)(y)之间的边的边权修改为(z)

    思路:

    找规律,答案仅与与根相连的(1)边个数的奇偶性有关。

    源代码:

    #include<set>
    #include<cstdio>
    #include<cctype>
    #include<algorithm>
    inline int getint() {
    	register char ch;
    	while(!isdigit(ch=getchar()));
    	register int x=ch^'0';
    	while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
    	return x;
    }
    const int N=4e4+1;
    bool b[N];
    std::set<int> set[N];
    int main() {
    	for(register int T=getint();T;T--) {
    		const int n=getint(),m=getint();
    		for(register int i=1;i<n;i++) {
    			const int u=getint(),v=getint();
    			if(getint()) {
    				set[u].insert(v);
    				set[v].insert(u);
    				b[u]^=1;
    				b[v]^=1;
    			}
    		}
    		for(register int i=0;i<m;i++) {
    			if(getint()) {
    				const int u=getint(),v=getint();
    				const bool w=getint();
    				if(!w&&set[u].count(v)) {
    					set[u].erase(v);
    					set[v].erase(u);
    					b[u]^=1;
    					b[v]^=1;
    				}
    				if(w&&!set[v].count(u)) {
    					set[u].insert(v);
    					set[v].insert(u);
    					b[u]^=1;
    					b[v]^=1;
    				}
    			} else {
    				puts(b[getint()]?"Girls win!":"Boys win!");
    			}
    		}
    		std::fill(&b[1],&b[n]+1,false);
    		for(register int i=1;i<=n;i++) {
    			set[i].clear();
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    mysql5.7安装
    win10 安装docker
    快速去水印(win10换图3D工具)
    爬虫---国家食品药品监督管理总局
    食品伙伴网爬虫
    驴妈妈旅游爬虫
    天气预测(CNN)
    ConcurrentDictionary线程不安全么,你难道没疑惑,你难道弄懂了么?
    C#线程篇---线程池如何管理线程(6完结篇)
    C#线程篇---Task(任务)和线程池不得不说的秘密(5)
  • 原文地址:https://www.cnblogs.com/skylee03/p/9740428.html
Copyright © 2011-2022 走看看