码迷,mamicode.com
首页 > 其他好文 > 详细

ARC078 D.Fennec VS. Snuke(树上博弈)

时间:2017-07-29 22:24:39      阅读:176      评论:0      收藏:0      [点我收藏+]

标签:logs   ons   auto   ios   end   bsp   延伸   颜色   int   

题目大意:

给定一棵n个结点的树

一开始黑方占据1号结点,白方占据n号结点

其他结点都没有颜色

每次黑方可以选择黑色结点临近的未染色结点,染成黑色

白方同理。

最后谁不能走谁输。

 

题解:

其实简单想想就可以想明白。

黑方肯定要往通往白方的最短路延伸,白方也是这样。

因为这样每次你可以最大化可行动次数。

所以先以1为根,dfs一遍,然后找到路径。

模拟一下走路径的过程,路径走光了就比谁的可行动次数多(有点像围棋的气的感觉),输出结果就可以了

 

#include <iostream>
#include <cstdio>
#include <deque>
#include <vector>
#include <vector>
using namespace std;
const int maxn = 1e5 + 100;
vector<int> G[maxn];
int deep[maxn], sz[maxn], f[maxn];
deque<int> Q;
void dfs(int x, int fa, int d){
    deep[x] = d;
    sz[x] = 1;
    f[x] = fa;
    for(auto to : G[x]){
        if(to == fa) continue;
        dfs(to, x, d+1);
        sz[x] += sz[to];
    }
}

int main()
{
    int n, x, y;
    cin>>n;
    for(int i = 1; i < n; i++){
        scanf("%d %d", &x, &y);
        G[x].push_back(y);
        G[y].push_back(x);
    }
    dfs(1, 1, 1);
    x = n;
    while(x != 1){
        Q.push_back(x);
        x = f[x];
    }
    Q.push_back(1);
    int ansB = 0, ansW = 0, B = 0, W, temp;
    while(1){
        if(Q.empty()){
            ansB += sz[B]-1-sz[W];
            ansW = sz[W] - ansW;
            if(ansB <= ansW) cout<<"Snuke"<<endl;
            else cout<<"Fennec"<<endl;
            return 0;
        }
        temp = B;
        B = Q.back(); Q.pop_back();
        if(temp != 0) ansB += sz[temp]-sz[B]-1;
        if(Q.empty()) {
            ansB += sz[B]-1-sz[W];
            ansW = sz[W] - ansW;
            if(ansW <= ansB) cout<<"Fennec"<<endl;
            else cout<<"Snuke"<<endl;
            return 0;
        }
        W = Q.front(); Q.pop_front();
        ansW++;
    }
}

 

ARC078 D.Fennec VS. Snuke(树上博弈)

标签:logs   ons   auto   ios   end   bsp   延伸   颜色   int   

原文地址:http://www.cnblogs.com/Saurus/p/7257537.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!