题意:两个人在有向上进行博弈,先手先下,后手在睡觉,所以后手由先手代下,每个人每次要沿着边移动,不能移动的人输,问最后先手是赢还是输还是平局,赢的话输出路径
题解:两个人进行博弈,先手帮后手下,所以先手的优势更大,只要从开始点经过环,那么先手不可能输
现在先考虑先手赢,从开始点直接搜就可以了,有环会进入死循环,所以一个点标记开始点到这个点步数的奇偶,如果走到这个点为奇数,而奇数被标记,那么就可以不继续搜这个点了
先手平局的情况是先手不能赢,而且能从开始点走到环
剩下的情况就是输了
#include <bits/stdc++.h> #define maxn 100010 #define INF 0x3f3f3f3f using namespace std; vector<int >G[maxn], ans; int dp[maxn][2], pre[maxn][2], out[maxn], n, m, t, a, flag = 0; bool vis[maxn]; void dfs(int x, int l) { vis[x] = true; for(int to : G[x]) { if(pre[to][l^1]==0) { pre[to][l^1] = x; dfs(to, l^1); } if(vis[to]) flag = 1; } vis[x] = false; } int main(){ scanf("%d%d", &n, &m); for(int i=1;i<=n;i++){ scanf("%d", &t); while(t--){ scanf("%d", &a); G[i].push_back(a); out[i]++; } } scanf("%d", &t); pre[t][0] = -1; dfs(t, 0); for(int i=1;i<=n;i++){ if(out[i] == 0&&pre[i][1]){ printf("Win\n"); t = 1; while(i!=-1){ ans.push_back(i); i = pre[i][t]; t ^= 1; } for(int i=ans.size()-1;i>=0;i--) printf("%d ", ans[i]); return 0; } } if(flag) printf("Draw\n"); else printf("Lose\n"); return 0; }