题意(经过转换):给你一个n个点m条边的有向图,再给你一个起点x,问存不存在一条路径满足①路径中有奇数条边;②终点的出度为0,如果存在输出Win,并在第二行输出这个路径(可能不唯一输出任意一种),否则你再看能不能通过这个点走进一个环中,如果可以输出Draw,环也走不进输出Lose
其实转成这个题意之后难度就降低了,因为一部分还是翻译+理解问题
判断是否为win:其实只用一个广搜就可以解决,vis[x][0/1]表示是否能在经过偶数/奇数条边的情况下到达点x,最后就是看有没有点x满足①出度为0;②vis[x][1]=1,如果有就是Win,输出路径的话直接用vis[][]记上一个点就行了
之后就是判断是否为Draw,也就是是否有环,这个就是有向图判环问题嘛,广搜求拓扑序或者深搜都可以
如果按以下方法写应该没有挂点
#include<stdio.h>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;
typedef struct
{
int x;
int t;
}Res;
Res now, temp;
vector<int> G[100005];
int ok, vis[100005][2], out[100005], flag[100005];
queue<Res> q;
void Print(int x, int y)
{
if(vis[x][y]!=-1)
Print(vis[x][y], y^1);
printf("%d ", x);
}
void Sech(int x)
{
int i, v;
flag[x] = 1;
for(i=0;i<G[x].size();i++)
{
v = G[x][i];
if(flag[v]==1)
ok = 1;
else if(flag[v]==0)
Sech(v);
}
flag[x] = 2;
}
int main(void)
{
int n, m, i, k, x;
scanf("%d%d", &n, &m);
for(i=1;i<=n;i++)
{
scanf("%d", &x);
out[i] = x;
while(x--)
{
scanf("%d", &k);
G[i].push_back(k);
}
}
scanf("%d", &k);
vis[k][0] = -1;
now.x = k, now.t = 0;
q.push(now);
while(q.empty()==0)
{
now = q.front();
q.pop();
for(i=0;i<G[now.x].size();i++)
{
temp.x = G[now.x][i];
temp.t = now.t^1;
if(vis[temp.x][temp.t]==0)
{
vis[temp.x][temp.t] = now.x;
q.push(temp);
}
}
}
for(i=1;i<=n;i++)
{
if(out[i]==0)
{
if(vis[i][1])
{
printf("Win\n");
Print(i, 1);
puts("");
return 0;
}
}
}
Sech(k);
if(ok)
printf("Draw\n");
else
printf("Lose\n");
return 0;
}