sgu - 520 - Fire in the Country(bfs + dfs + 博弈)

来源:互联网 发布:淘宝卖家如何发布宝贝 编辑:程序博客网 时间:2024/05/22 18:29

题意:n个点m条边的无向连通图,开始时结点1起火,火蔓延到其相邻点需1天,开始时有个机器人也在结点1处,但机器人先走了,结点1才起火,Vladimir与Nikolay轮流控制这个机器人,机器人1天也只能移动到另一个相邻点,最后谁不得不让机器人走向火海谁就败,输出胜者。

题目链接:http://acm.sgu.ru/problem.php?contest=0&problem=520

——>>搜索中的博弈,策略:让火跟着走,走进死胡同,下一天对手就没得走了(若子状态有一个先手必败状态,那么现在这个状态是先手必胜状态)。

f[i]表示火蔓延到结点i要多少天。

#include <cstdio>#include <cstring>#include <queue>using namespace std;const int maxn = 1000 + 10;int n, m, head[maxn], nxt[maxn<<1], u[maxn<<1], v[maxn<<1], ecnt, f[maxn];void init(){    for(int i = 1; i <= n; i++) head[i] = -1;    ecnt = 0;}void addEdge(int uu, int vv){    u[ecnt] = uu;    v[ecnt] = vv;    nxt[ecnt] = head[uu];    head[uu] = ecnt;    ecnt++;}void read(){    int i, uu, vv;    for(i = 0; i < m; i++){        scanf("%d%d", &uu, &vv);        addEdge(uu, vv);        addEdge(vv, uu);    }}void bfs(){    queue<int> qu;    while(!qu.empty()) qu.pop();    f[1] = 1;    qu.push(1);    while(!qu.empty()){        int u = qu.front(); qu.pop();        for(int e = head[u]; e != -1; e = nxt[e]) if(!f[v[e]]){            f[v[e]] = f[u] + 1;            qu.push(v[e]);        }    }}void fire(){    memset(f, 0, sizeof(f));    bfs();}bool dfs(int u){    for(int e = head[u]; e != -1; e = nxt[e]) if(f[v[e]] == f[u] + 1 && !dfs(v[e])) return 1;    return 0;}int main(){    while(scanf("%d%d", &n, &m) == 2){        init();        read();        fire();        if(dfs(1)) printf("Vladimir\n");        else printf("Nikolay\n");    }    return 0;}


原创粉丝点击