[图论][BFS]Fennec VS. Snuke

题目描述

Fennec and Snuke are playing a board game.
On the board, there are N cells numbered 1 through N, and N−1 roads, each connecting two cells. Cell ai is adjacent to Cell bi through the i-th road. Every cell can be reached from every other cell by repeatedly traveling to an adjacent cell. In terms of graph theory, the graph formed by the cells and the roads is a tree.
Initially, Cell 1 is painted black, and Cell N is painted white. The other cells are not yet colored. Fennec (who goes first) and Snuke (who goes second) alternately paint an uncolored cell. More specifically, each player performs the following action in her/his turn:
Fennec: selects an uncolored cell that is adjacent to a black cell, and paints it black.
Snuke: selects an uncolored cell that is adjacent to a white cell, and paints it white.
A player loses when she/he cannot paint a cell. Determine the winner of the game when Fennec and Snuke play optimally.

Constraints
2≤N≤105
1≤ai,bi≤N
The given graph is a tree.

输入

Input is given from Standard Input in the following format:
N
a1 b1
:
aN−1 bN−1

输出

If Fennec wins, print Fennec; if Snuke wins, print Snuke.

样例输入

7
3 6
1 2
3 1
7 4
5 7
1 4

样例输出

Fennec

提示

For example, if Fennec first paints Cell 2 black, she will win regardless of Snuke‘s moves.

思路:思路很容易想,关键是我忘了怎么用vector来构建邻接表了!!

AC代码:

#include <iostream>
#include<cstdio>
#include<vector>
#include<queue>
#include<cstring>
using namespace std;

vector<int> edge[100005];//相当于二维数组int edge[100005][可变长];
queue<int> q;
int vis[100005];
int step[100005];
int pre[100005];
int flag[100005];
int n;
int x=1,y=1;

int bfs1(){//目的是找到从1到n的那条路
   vis[1]=1; step[1]=0; pre[1]=0; q.push(1);
   while(!q.empty()){
     int head=q.front(); q.pop();
     if(head==n) return step[head];
     for(int i=0;i<(int)edge[head].size();i++){
        int nxt=edge[head][i];
        if(vis[nxt]) continue;
        step[nxt]=step[head]+1;
        vis[nxt]=1;
        pre[nxt]=head;
        q.push(nxt);
     }
   }
   return -1;
}

void bfs2(){//目的是求出在双方最佳策略下,black和white的数量
   while(!q.empty()) q.pop();
   memset(vis,0,sizeof(vis));
   vis[1]=1; q.push(1);
   while(!q.empty()){
     int head=q.front(); q.pop();
     for(int i=0;i<(int)edge[head].size();i++){
        int nxt=edge[head][i];
        if(vis[nxt]||flag[nxt]==2||nxt==n) continue;
        vis[nxt]=1; x++;
        q.push(nxt);
     }
   }
}

int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n-1;i++){//邻接表存图
        int a,b;
        scanf("%d%d",&a,&b);
        edge[a].push_back(b);
        edge[b].push_back(a);
    }
    int tmp=bfs1(); tmp--,tmp/=2;//tmp表示在1到n的线路上有几个white
    int now=pre[n]; int cnt=0;
    while(pre[now]!=0){//对线路上的点进行标记——flag[i]=1表示该点black,flag[i]=2表示该点white
        flag[now]=2; cnt++;
        if(cnt>tmp) flag[now]=1;
        now=pre[now];
    }
    bfs2();
    y=n-x;
    if(x<=y) printf("Snuke\n");
    else printf("Fennec\n");
    return 0;
}

原文地址:https://www.cnblogs.com/lllxq/p/9280959.html

时间: 2024-10-11 01:00:16

[图论][BFS]Fennec VS. Snuke的相关文章

Fennec VS. Snuke

Fennec VS. Snuke Time limit : 2sec / Memory limit : 256MB Score : 400 points Problem Statement Fennec and Snuke are playing a board game. On the board, there are N cells numbered 1 through N, and N−1 roads, each connecting two cells. Cell ai is adjac

图论 --- BFS + MST

Borg Maze Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 7844   Accepted: 2623 Description The Borg is an immensely powerful race of enhanced humanoids from the delta quadrant of the galaxy. The Borg collective is the term used to descr

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

题目大意: 给定一棵n个结点的树 一开始黑方占据1号结点,白方占据n号结点 其他结点都没有颜色 每次黑方可以选择黑色结点临近的未染色结点,染成黑色 白方同理. 最后谁不能走谁输. 题解: 其实简单想想就可以想明白. 黑方肯定要往通往白方的最短路延伸,白方也是这样. 因为这样每次你可以最大化可行动次数. 所以先以1为根,dfs一遍,然后找到路径. 模拟一下走路径的过程,路径走光了就比谁的可行动次数多(有点像围棋的气的感觉),输出结果就可以了 #include <iostream> #includ

数据结构之 图论---bfs(邻接表)

数据结构实验之图论二:基于邻接表的广度优先搜索遍历 Time Limit: 1000MS Memory limit: 65536K 题目描述 给定一个无向连通图,顶点编号从0到n-1,用广度优先搜索(BFS)遍历,输出从某个顶点出发的遍历序列.(同一个结点的同层邻接点,节点编号小的优先遍历) 输入 输入第一行为整数n(0< n <100),表示数据的组数. 对于每组数据,第一行是三个整数k,m,t(0<k<100,0<m<(k-1)*k/2,0< t<k),

图论 BFS总结

1.关于BFS的Key_word: ①hash或状态压缩记录状态  ②状态剪枝 ③反向BFS ④双向BFS ⑤特殊初始化VIS数组 ⑥动态图的搜索 ⑦优先队列优化搜索 ⑧数位搜索 下面是一一讲解: 1.hash或状态压缩记录状态 : 当状态太多而且边界也广时数组难以存储状态时或者题目对空间的要求较为苛刻,这时候就要使用状态压缩来保存所需的状态或者hash的方式将一个状态对应为一个整数通过一维数组来记录是否访问,当数据过于离散时可以考虑使用map,但是相应的时间复杂度也会上升,如果真的要将所有状态

BFS学习总结

BFS学习总结 给你一个n*m的网格迷宫,迷宫中有些格子不能走,其他的格子都能走.然后给你起点与终点,问你从起点走到终点最少需要多少步? 上面的问题就是一个典型的BFS问题,对于这类问题来说,只要你掌握了这类问题的关键思想,其实他们都是可以用类似的思路来做的. 你可以把BFS问题想象成:从一个父亲(起点状态)生儿子(后继状态),儿子又生孙子(后继状态)的过程,只要这个家族中出生了一个满意的后代(终点状态),这个家族就不生了. 但是如果这个家族中有两个完全一样的人出生(他们的辈分不一定相同),那么

BDFZOI 树的直径

提交次数:2 涉及知识:基础图论/BFS 描述 一棵树T的"直径"定义为结点两两间距离的最大值.给定带权树T,求T的直径长度. 输入 第一行包含2个整数N.M,表示图中共有N个结点和M条无向边.(N <= 5000,M<n)接下来M行,每行包含3个整数{u,v,w},表示有一条无向边连接结点u.v*输入保证是无环图输出一个整数,代表直径长度 样例输入 4 31 2 12 3 22 4 3 样例输出 5 代码: 1 #include<iostream> 2 #in

CodeForces Round #285 Div.2

C.Misha and Forest (图论 BFS) 比赛进行了一半才想起来有场CF没打,=_=|| 前两道题快速切掉,C题一直卡没什么好的思路 憋了几天,忍不住偷偷瞄了一下别人AC的代码,发现我题没看清题目,题中说了给出的图是森林. 于是切入点找到了! 题意: 一个由n个节点构成的森林,编号从0到n-1,给出每个节点的 度数 和 相邻节点编号的异或和,输出图中的边数和所有邻接节点的编号. 分析: 因为是森林,所以图中的叶子节点就是突破口.叶子节点最明显的特征就是: 度数为1 它相邻节点编号的

图论算法之DFS与BFS

概述(总) DFS是算法中图论部分中最基本的算法之一.对于算法入门者而言,这是一个必须掌握的基本算法.它的算法思想可以运用在很多地方,利用它可以解决很多实际问题,但是深入掌握其原理是我们灵活运用它的关键所在. 含义特点 DFS即深度优先搜索,有点类似广度优先搜索,也是对一个连通图进行遍历的算法.它的思想是从一个顶点V0开始,沿着一条路一直走到底,如果发现不能到达目标解,那就返回到上一个节点,然后从另一条路开始走到底,这种尽量往深处走的概念即是深度优先的概念. 由于用到递归,当节点特别多且深度很大