撒,让我们开始游戏吧!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#include<bits/stdc++.h>
#define N 2010
#include<queue>
using namespace std;
int tot,ans,head[3*N],out[3*N],SG[N],flag[N],f[N];
queue<int> q;
struct edge{
int to,next;
}a[3*N],e[3*N];
inline int read()
{
int x=0,f=1;
char ch;
ch = getchar();
while(!isdigit(ch))
{
if(ch == '-') f = -f;
ch = getchar();
}
while(isdigit(ch))
{
x = x*10+ch-'0';
ch = getchar();
}
return f*x;
}
inline void add(int x,int y)
{
tot++;
a[tot] = (edge){y,head[x]}; head[x] = tot;
e[tot] = (edge){x,f[y]}; f[y] = tot;
}
int main()
{
int n,m,k,i,j,v,x,y,maxx;
n = read(),m = read(), k = read();
for(i = 1; i <= m; i++)
{
x = read(),y = read();
out[x]++;
add(x,y);
}
for(i = 1; i <= n; i++)
if(!out[i]) q.push(i);
while(!q.empty()) //类似拓扑排序
{
i = q.front();
q.pop();
maxx = 0;
for(j = head[i]; j; j = a[j].next)
{
v = a[j].to;
flag[SG[v]] = 1;
maxx = max(maxx,SG[v]);
}
for(j = 0; j <= maxx+1; j++) if(!flag[j]) break;//mex运算
SG[i] = j;
for(j = 0; j <= maxx; j++) flag[j] = 0;
for(j = f[i]; j; j = e[j].next)
{
v = e[j].to;
out[v]--;
if(!out[v]) q.push(v);
}
}
//prepare
for(i = 1; i <= k; i++)
{
int num;
num = read();
ans = ans^SG[num];
}
if(ans) printf("Shiro win!\n");
else printf("Sora win!\n");
return 0;
}