zoukankan      html  css  js  c++  java
  • SEERC 2019 F. Game on a Tree

    题意:

    给一棵树,先手可以任意选一个点染色,接下来每个人可以将当前点的一个祖先或一个孩子染色,一个点只能被染色一次,谁无点可以染色谁就输了。

    解法

    对于一个点,可以到达的点有所有祖先和所有孩子。如果u可以到达v节点,那么v节点显然也可以到达u节点。
    此时我们可以考虑将树上博弈转化成图。n个节点,每个点与可到达的节点连边,就会形成一张图。
    手玩几个例子,大概可以发现当最大匹配是完美匹配的时候后手必胜,否则先手必胜。下面给出证明。

    1.最大匹配是完美匹配时,后手必胜。

    因为完美匹配,所以n个点必可以分成n/2组,((v_1,v_2),(v_3,v_4)...(v_{n-1},v_n)),那么先手每选一个点,后手就选与之同组的一个点。那么先手必将在某一步无路可走。后手必胜。

    2.最大匹配不是完美匹配时,先手必胜。

    设最大匹配(E={(v_1,v_2),(v_3,v_4)...(v_{k-1},v_k)})。那么先手选一个不在匹配内的点,会发生以下两种情况:
    (1)后手选择匹配内的点。
    此时先手如同1进行操作就可以必胜。因为如果后手在某一轮选择一个匹配外的点,例如在(v_4)后选择一个匹配外的点,我们就会发现((v_a,v_1),(v_2,v_3)(v_4,v_b))是可达的,那么({(v_a,v_1),(v_2,v_3)(v_4,v_b)...(v_{k-1},v_k)})就是一个更大的匹配,与假设不符。所以后手无法再次选择匹配外的点,游戏如1进行,先手此时必胜。
    (2)后手也选择匹配外的点。
    那么很显然,((v_a,v_b))是可达的,可以加入最大匹配,与假设不符。不可能。
    所以,最大匹配不是完美匹配时,先手必胜。

    于是,题目就转换成了求由这棵树构成的图是否具有完美匹配。树DP即可。

    #include <bits/stdc++.h>
    using namespace std;
    
    const int maxn = 1e5;
    int f[maxn + 11];
    vector <int> edge[maxn + 11];
    
    void dfs(int x,int fa) {
    	for (auto v : edge[x]) {
    		if (v == fa) continue;
    		dfs(v , x);
    		f[x] += f[v];
    	}
    	if (f[x]) f[x] -= 1;
    	else f[x] = 1;
    }
    
    int main(){
    	int n;
    	scanf("%d",&n);
    	for (int i = 1; i < n; i++) {
    		int u,v;
    		scanf("%d %d",&u,&v);
    		edge[u].push_back(v);
    		edge[v].push_back(u);
    	}
    	dfs(1 , 0);
    	if (!f[1]) printf("Bob
    "); else printf("Alice
    ");
    } 
    
  • 相关阅读:
    【微信小程序】后台访问-net::ERR_CONNECTION_REFUSED 及 不是request合法域名问题 的解决
    【微信小程序】引用FontAwesome字体
    【微信小程序】开发工具使用技巧(七)
    【微信小程序】小程序扩展能力(六)
    【微信小程序】小程序云开发(五)
    【微信小程序】小程序框架(四)
    javascript学习笔记
    HTML&CSS学习笔记
    mysql学习笔记
    c++ primer 笔记 (四)
  • 原文地址:https://www.cnblogs.com/Embiid/p/12617850.html
Copyright © 2011-2022 走看看