Gym100548H

来源:互联网 发布:淘宝网家纺四件套 编辑:程序博客网 时间:2024/06/06 18:57

2014西安赛区的H,是一道有向图上的博弈问题
首先我们要确定一下结束状态,一种是两点重合,还有一种是没法移动棋子
接下来我们把结束状态放在队列的队首,倒退之前的状态
我用1表示Alice必胜,2表示Bob必胜,3表示平局,分了4种情况
1、轮到Bob,状态为1,dp[x][y][1]=1,那么之前能到达y的点dp[x][v][0]=1
2、轮到Alice,状态为2,dp[x][y][0]=2,那么x的入度v,dp[v][y][1]=2
3、轮到Bob,状态为2,那么对于y的入度v,vis[x][v][y][0]=1,v不能移动到y
4、轮到Alice,状态为1,与3的情况类似

#include<bits/stdc++.h>using namespace std;const int maxn=100+10;struct node{  int x,y,st;};int dp[maxn][maxn][2],n,m,T,cnt[maxn][maxn][2];bool vis[maxn][maxn][maxn][2];queue<node> Q;vector<int> g[maxn];vector<int> h[maxn];void work(){  while(!Q.empty())  {    node x=Q.front();Q.pop();    if(x.st==1&&dp[x.x][x.y][x.st]==1)    {      for(int i=0;i<h[x.y].size();i++)      {        int v=h[x.y][i];        if(!dp[x.x][v][0])        {          dp[x.x][v][0]=1;          Q.push((node){x.x,v,0});        }      }    }    else if(x.st==0&&dp[x.x][x.y][x.st]==2)    {      for(int i=0;i<h[x.x].size();i++)      {        int v=h[x.x][i];        if(!dp[v][x.y][1])        {          dp[v][x.y][1]=2;          Q.push((node){v,x.y,1});        }      }    }    else if(x.st==0&&dp[x.x][x.y][x.st]==1)    {      for(int i=0;i<h[x.x].size();i++)      {        int v=h[x.x][i];        if(!vis[v][x.y][x.x][1])        {          vis[v][x.y][x.x][1]=1;cnt[v][x.y][1]++;          if(cnt[v][x.y][1]==g[v].size()&&!dp[v][x.y][1])          {            dp[v][x.y][1]=1;            Q.push((node){v,x.y,1});          }        }      }    }    else if(x.st==1&&dp[x.x][x.y][x.st]==2)    {      for(int i=0;i<h[x.y].size();i++)      {        int v=h[x.y][i];        if(!vis[x.x][v][x.y][0])        {          vis[x.x][v][x.y][0]=1;cnt[x.x][v][0]++;          if(cnt[x.x][v][0]==g[v].size()&&!dp[x.x][v][0])          {            dp[x.x][v][0]=2;            Q.push((node){x.x,v,0});          }        }      }    }  }}int main(){  //freopen("test.in","r",stdin);  scanf("%d",&T);  for(int tt=1;tt<=T;tt++)  {    scanf("%d%d",&n,&m);    memset(dp,0,sizeof(dp));memset(vis,0,sizeof(vis));    memset(cnt,0,sizeof(cnt));    for(int i=1;i<=n;i++)    {      h[i].clear();g[i].clear();      dp[i][i][0]=dp[i][i][1]=1;      Q.push((node){i,i,0});Q.push((node){i,i,1});    }    for(int i=1;i<=m;i++)    {      int u,v;scanf("%d%d",&u,&v);      h[v].push_back(u);      g[u].push_back(v);    }    for(int i=1;i<=n;i++)      for(int j=1;j<=n;j++)        if(i!=j)        {          if(!g[i].size())            dp[i][j][1]=1;Q.push((node){i,j,1});          if(!g[j].size())            dp[i][j][0]=2;Q.push((node){i,j,0});        }    work();    int sx,sy;scanf("%d%d",&sx,&sy);    cout<<"Case #"<<tt<<": ";    if(dp[sx][sy][1]!=1) puts("Yes");    else puts("No");  }  return 0;}
0 0
原创粉丝点击