2014西安 H 有向图博弈 UVALive-7042
这个 类似于之前一个CF的题,直接从必败态倒着出发。
如果一个点能到达的点都是自己的必败态,那么他就是必败态。
in other word -- 如果一个点能到达的点都是敌人的必胜态,那么他就是必败态。
如果一个点能到达一个自己的必胜态,那么他就是必胜态。
in other word -- 如果一个点能到达一个敌人的必败态,那么他就是必胜态。
http://www.cnblogs.com/HITLJR/p/6613061.html
WZK的代码
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <bits/stdc++.h> 2 #define maxn 110 3 #define inf 0x3f3f3f3f 4 #define REP(i,x,y) for(int i=x;i<(y);i++) 5 #define RREP(i,x,y) for(int i=x;i>(y);i--) 6 using namespace std; 7 typedef long long ll; 8 typedef pair<int,int>pii; 9 int n,m; 10 vector<int>e[maxn]; 11 int cnt[maxn][maxn][2],dp[maxn][maxn][2],vis[maxn][maxn][2],out[maxn]; 12 struct P{ 13 int pos_b,pos_a,op; 14 P(){} 15 P(int _,int __,int ___):pos_b(_),pos_a(__),op(___){} 16 }; 17 int main() 18 { 19 int T,cas=1;scanf("%d",&T); 20 while(T--) { 21 queue<P>que; 22 scanf("%d %d",&n,&m); 23 for(int i=1;i<=n;i++) { 24 out[i]=0; 25 for(int j=1;j<=n;j++) { 26 dp[i][j][0]=dp[i][j][1]=-1; 27 vis[i][j][0]=vis[i][j][1]=0; 28 } 29 e[i].clear(); 30 } 31 REP(i,1,m+1) { 32 int u,v;scanf("%d %d",&u,&v); 33 e[v].push_back(u); 34 out[u]++; 35 } 36 REP(i,1,n+1) {vis[i][i][0]=1;dp[i][i][0]=0,que.push(P(i,i,0));} 37 REP(i,1,n+1) {vis[i][i][1]=1;dp[i][i][1]=1,que.push(P(i,i,1));} 38 REP(op,0,2) { //0 Bob 1 Alice 39 REP(i,1,n+1) { 40 REP(j,1,n+1) { 41 if(i==j) continue; 42 if(op==0) { 43 if(out[i]==0) { 44 dp[i][j][op]=0,que.push(P(i,j,op)); 45 vis[i][j][op]=1; 46 } 47 // else if(out[i]==1&&pre[i][0]==j) dp[i][j][op]=0,que.push(P(i,j,op)); 48 } 49 else { 50 if(out[j]==0) { 51 dp[i][j][op]=0,que.push(P(i,j,op)); 52 vis[i][j][op]=1; 53 } 54 } 55 } 56 } 57 } 58 REP(i,1,n+1) REP(j,1,n+1) cnt[i][j][0]=out[i]; 59 REP(i,1,n+1) REP(j,1,n+1) cnt[i][j][1]=out[j]; 60 while(!que.empty()) { 61 P now=que.front();que.pop(); 62 63 int v1=now.pos_b,v2=now.pos_a; 64 // cout << v1 <<" "<< v2 <<" " << now.op <<" "<<dp[v1][v2][now.op]<< endl; 65 // cout<<v1<<" "<<v2<<" "<<now.op<<endl; 66 if(!now.op) { //bob 67 int Size=e[v2].size(); 68 REP(i,0,Size) { 69 if(dp[v1][v2][now.op]==0) { 70 if(vis[v1][e[v2][i]][1]) continue; 71 dp[v1][e[v2][i]][1]=1; 72 vis[v1][e[v2][i]][1]=1; 73 que.push(P(v1,e[v2][i],1)); 74 } 75 else if(dp[v1][v2][now.op]) { 76 if(vis[v1][e[v2][i]][1]) continue; 77 cnt[v1][e[v2][i]][1]--; 78 if(cnt[v1][e[v2][i]][1]==0) { 79 dp[v1][e[v2][i]][1]=0; 80 que.push(P(v1,e[v2][i],1)); 81 vis[v1][e[v2][i]][1]=1; 82 } 83 } 84 } 85 } 86 else { //Alice 87 int Size=e[v1].size(); 88 // cout<<Size<<endl; 89 REP(i,0,Size) { 90 if(dp[v1][v2][now.op]==0) { 91 if(vis[e[v1][i]][v2][0]) continue; 92 dp[e[v1][i]][v2][0]=1; 93 vis[e[v1][i]][v2][0]=1; 94 que.push(P(e[v1][i],v2,0)); 95 } 96 else if(dp[v1][v2][now.op]) { 97 if(vis[e[v1][i]][v2][0]) continue; 98 cnt[e[v1][i]][v2][0]--; 99 if(cnt[e[v1][i]][v2][0]==0) { 100 dp[e[v1][i]][v2][0]=0; 101 que.push(P(e[v1][i],v2,0)); 102 vis[e[v1][i]][v2][0]=1; 103 } 104 } 105 } 106 } 107 } 108 int x,y;scanf("%d %d",&x,&y); 109 printf("Case #%d: ",cas++); 110 //cout<<dp[x][y][0]<<endl; 111 if(dp[x][y][0]) puts("Yes"); 112 else puts("No"); 113 } 114 }