UVALive 3695 (博弈 bfs)

来源:互联网 发布:怎么减少网络延迟 编辑:程序博客网 时间:2024/06/06 00:58

题目链接:点击这里

题意:一个有向图,alice和bob初始在某一个点,然后bob先手每人移动一步,移动到不能移动的人输,在同一个点算bob输,死局算bob输。问先手是否必胜。

经典的博弈论,非赢即输。站在bob的视角,先手必败当且仅当能够到达的都是必败态,必胜当且仅当能到达一个必胜态。所以维护所有的必败态(对于bob而言的),初始是在同一个点的状态和bob先手并且没有出边的状态,然后根据当前状态bfs前一个状态判断前一个状态是不是必败态。

#include <cstdio>#include <cmath>#include <algorithm>#include <iostream>#include <vector>#include <queue>#include <cstring>using namespace std;#define maxn 105#define maxm 5100005int g[maxn][maxn];int n, m;int degree[maxn];//出度int num[maxn][maxn];//是多少个必败态的前一状态int dp[maxn][maxn][2];//alice bob 0:alice 1:bobstruct node {    int x, y;    int id;};queue <node> q;bool bfs () {    while (!q.empty ()) {        node now = q.front (); q.pop ();        if (now.id == 0) {//这一步是alice先手 上一步是bob先手            for (int i = 1; i <= n; i++) if (g[i][now.y]) { //cout << i << endl;                num[now.x][i]++;                if (num[now.x][i] == degree[i]) {//alice在x bob走到的每一处都是必败态                    dp[now.x][i][1] = 1;                    q.push ((node) {now.x, i, 1});                }            }        }        else {//这一步是bob先手 上一步是alice先手            for (int i = 1; i <= n; i++) if (g[i][now.x]) {                if (dp[i][now.y][0])//已经选择过了 避免重复bfs                    continue;                dp[i][now.y][0] = 1;                q.push ((node) {i, now.y, 0});            }        }    }    int v, u;//bob alice    scanf ("%d%d", &v, &u);    if (dp[u][v][1])        return 0;    return 1;}int main () {    int t, kase = 0;    scanf ("%d", &t);    while (t--) {        scanf ("%d%d", &n, &m);        memset (num, 0, sizeof num);        memset (g, 0, sizeof g);        memset (degree, 0, sizeof degree);        memset (dp, 0, sizeof dp);        for (int i = 0; i < m; i++) {            int u, v;            scanf ("%d%d", &u, &v);            g[u][v] = 1;            degree[u]++;        }        while (!q.empty ())            q.pop ();        for (int i = 1; i <= n; i++) {//在同一个节点            dp[i][i][0] = dp[i][i][1] = 1;            q.push ((node) {i, i, 0});            q.push ((node) {i, i, 1});        }        for (int i = 1; i <= n; i++) {//bob先手并且无路可走            for (int j = 1; j <= n; j++) if (i != j) {                if (degree[j] == 0) {                    dp[i][j][1] = 1;                    q.push ((node) {i, j, 1});                }            }        }        //bfs ();        printf ("Case #%d: %s\n", ++kase, bfs () ? "Yes" : "No");    }    return 0;}
0 0
原创粉丝点击