1. 程式人生 > >CodeForces 937D Sleepy Game

CodeForces 937D Sleepy Game

ring com als size 移動 spa get memset targe

Sleepy Game

題意:Petya and Vasya 在玩移動旗子的遊戲, 誰不能移動就輸了。 Vasya在訂移動計劃的時候睡著了, 然後Petya 就想趁著Vasya睡著的時候同時定下策略, 如果可以贏得話輸出Win 並輸出路徑, 如果步數在達到1e6的情況下,就認定為平局, 輸出Draw,如果輸的話就輸出lost。

題解:每個點以奇偶的步數通過就能確定是否為贏, 如果偶數步走到這個點, 那麽下次再偶數走過這個點, 那麽這個點上次通過的點的步數奇偶就不變了, 就不需要走了。

可以用Tarjian 縮環, 然後標記一下成環的點, 這樣如果走路的時候訪問到這個點, 那麽就算至少也可以到達平局。

然後在走到沒有路的點,然後判斷一下奇偶就好了。

代碼:

 1 #include<iostream>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<cmath>
 5 #include<cstdio>
 6 using namespace std;
 7 const int N = 1e6+10;
 8 struct Node{
 9     int to;
10     int nt;
11 }e[N];
12 int tot = 0;
13 int head[N], vis[N], ans[N], last[N];
14 int instack[N], low[N], dfn[N], vvis[N], Stack[N]; 15 int ccnt = 0, top = 0; 16 void add_edge(int u, int v){ 17 e[tot].to = v; 18 e[tot].nt = head[u]; 19 head[u] = tot++; 20 } 21 void Tar(int u){ 22 instack[u] = 1, vvis[u] = 1; 23 low[u] = dfn[u] = ccnt++; 24 Stack[++top] = u;
25 for(int i = head[u]; ~i; i = e[i].nt){ 26 int v = e[i].to; 27 if(!vvis[v]) Tar(v); 28 if(instack[v]) low[u] = min(low[v], low[u]); 29 } 30 if(low[u] == dfn[u]){ 31 if(Stack[top] == u){ 32 top--; 33 instack[u] = 0; 34 return; 35 } 36 while(1){ 37 int v = Stack[top--]; 38 vvis[v] = -1; 39 instack[v] = 0; 40 if(v == u) break; 41 } 42 } 43 } 44 bool draw = false, win = false; 45 int ans_cnt = 0; 46 int max_n = 1e6; 47 void dfs(int u, int cnt){ 48 if(win) return ; 49 if(cnt >= max_n) {draw = true; return;} 50 if(vis[u] == -1) return; 51 if(vvis[u] == -1) draw = true; 52 vis[u]++; 53 ans[cnt] = u; 54 if(vis[u] == 1) last[u] = cnt; 55 if(vis[u] > 1 && (cnt-last[u])%2 == 0) {return ;} 56 if(vis[u] > 1 && (cnt-last[u])%2 == 1) 57 {vis[u] = -1;} 58 if(head[u] == -1 && cnt&1) {win = true; ans_cnt = cnt ; return;} 59 for(int i = head[u]; ~i; i = e[i].nt){ 60 dfs(e[i].to, cnt+1); 61 } 62 } 63 int main(){ 64 int n, m; 65 scanf("%d%d",&n,&m); 66 int t, v; 67 memset(head, -1, sizeof(head)); 68 memset(last, -1, sizeof(last)); 69 for(int i = 1; i <= n; i++){ 70 scanf("%d",&t); 71 for(int j = 1; j <= t; j++){ 72 scanf("%d",&v); 73 add_edge(i,v); 74 } 75 } 76 for(int i = 1; i <= n; i++) 77 if(!vvis[i]) Tar(i); 78 scanf("%d",&v); 79 dfs(v,0); 80 if(win){ 81 printf("Win\n"); 82 for(int i = 0; i <= ans_cnt; i++) 83 printf("%d%c",ans[i]," \n"[i == ans_cnt]); 84 } 85 else if(draw) 86 printf("Draw\n"); 87 else printf("Lose\n"); 88 return 0; 89 }

CodeForces 937D Sleepy Game