题意:
在一个DAG上的一些顶点上有棋子,每次轮流移动一个,移动一步,只能按照有向边移动。如果没有可以移动的为负。
思路:
基础的DAG上的求sg函数,好久没有写过了,调了好久。
代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
using namespace std;
typedef long long ll;
int N,C,Q,x,q,cas,res;
vector<int>p[10010];
bool vis[10010];
int sg[10010];
vector<int>num;
void dfs(int x)
{
vis[x]=true;
vector<int>S;//不用vector这道题会爆栈
S.clear();
for(int i=0; i<(int)p[x].size(); i++)
{
if(!vis[p[x][i]])
dfs(p[x][i]);
S.push_back(sg[p[x][i]]);
}
int t=0;
sort(S.begin(),S.end());
for(int i=0; i<(int)S.size(); i++)
{
if(t==S[i])
{
t++;
}
else if(t<S[i])
{
break;
}
}
sg[x]=t;
}
int main()
{
#ifdef untitiled1
//freopen("in.in","r",stdin);
#endif // untitiled1
cas=1;
while(scanf("%d",&N)!=EOF)
{
p[N].clear();
for(int i=1; i<=N-1; i++)
{
scanf("%d",&C);
p[i].clear();
for(int j=1; j<=C; j++)
{
scanf("%d",&x);
p[i].push_back(x);
}
}
memset(vis,false,sizeof(vis));
for(int i=1; i<=N; i++)
{
if(!vis[i])
dfs(i);
}
printf("Case %d:\n",cas);
scanf("%d",&Q);
for(int q=1; q<=Q; q++)
{
int t1;
scanf("%d",&t1);
res=0;
for(int i=1; i<=t1; i++)
{
scanf("%d",&x);
res^=sg[x];
}
if(res==0)
{
printf("Bob\n");
}
else
{
printf("Alice\n");
}
}
cas++;
}
return 0;
}