[CF936B] Sleepy Game - DFS,BFS
Description
有向图上指定一个起点。若存在一条到叶子距离为奇数的路径(注意这里的路径不一定是最短路径),则必胜。若不存在,但是可以到达一个回路,则可以平局。上述两种都不能达到,则失败。
Solution
这里实际上是两个问题
- 是否存在一条到叶子距离为奇数的路径
- 是否能走到一个环
对于问题 1,我们用图 dp 的方法做,即建立分层图然后 BFS,具体地,图分为奇层和偶层,起点在偶层上,连边永远在相邻层中连
对于问题 2,DFS 一遍,始终标记栈中结点,如果能走回栈中结点,那么就有环
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 2e5 + 5;
int s;
int n, m;
vector<int> g[N];
int vis[N];
void dfs(int p)
{
vis[p] = 1;
for (int q : g[p])
{
if (vis[q] == 0)
{
dfs(q);
}
else
{
cout << "Draw" << endl;
exit(0);
}
}
vis[p] = 0;
}
namespace solution
{
vector<int> g[N];
int vis[N], from[N];
void main()
{
for (int i = 1; i <= n; i++)
{
for (int q : (::g[i]))
{
g[i].push_back(q + n);
g[i + n].push_back(q);
}
}
queue<int> que;
que.push(s);
vis[s] = 1;
while (que.size())
{
int p = que.front();
que.pop();
for (int q : g[p])
{
if (!vis[q])
{
vis[q] = 1;
from[q] = p;
que.push(q);
}
}
}
for (int i = n + 1; i <= 2 * n; i++)
{
if (g[i].size() == 0 && vis[i])
{
cout << "Win" << endl;
vector<int> ans;
int p = i;
while (p)
ans.push_back(p), p = from[p];
while (ans.size())
{
int t = ans.back();
ans.pop_back();
if (t > n)
t -= n;
cout << t << " ";
}
exit(0);
}
}
}
} // namespace solution
signed main()
{
ios::sync_with_stdio(false);
cin >> n >> m;
for (int i = 1; i <= n; i++)
{
int t;
cin >> t;
while (t--)
{
int x;
cin >> x;
g[i].push_back(x);
}
}
cin >> s;
solution::main();
dfs(s);
cout << "Lose" << endl;
}