1. 程式人生 > >Gym 101246D Fire in the Country(dfs求SG函數)

Gym 101246D Fire in the Country(dfs求SG函數)

tor 我們 style sizeof std clas mem class ==

http://codeforces.com/gym/101246/problem/D

題意:

給定一個無向有環圖,大火從1點開始,每個時間點與它相鄰的點也將會著火,現在有兩個人輪流操作機器人,機器人從1點出發,每個人每次選擇一個點走,誰最後被火燒了誰就輸了。

思路:

博弈題。

我們先預處理求出每個點著火的時間點,然後根據時間點重建新圖,也就是重新建一個有向無環圖,原來圖中相連的並且時間點相差1的相連,由時間低的連向時間高的。

接下來我們在新圖上求每個點的SG值,SG值為0的點就是葉子結點,這樣父親結點的SG值就可以通過子節點的SG值求出,也就是求mex。

最後我們可以求出根結點的SG值,也就是SG【1】的值。

  1 #include<iostream>
  2 #include<algorithm>
  3 #include<cstring>
  4 #include<cstdio>
  5 #include<sstream>
  6 #include<vector>
  7 #include<stack>
  8 #include<queue>
  9 #include<cmath>
 10 #include<map>
 11 #include<cstdio>
 12
#include<set> 13 using namespace std; 14 typedef long long ll; 15 typedef pair<int,int> pll; 16 const int INF = 0x3f3f3f3f; 17 const int maxn=1000+5; 18 19 int n, m; 20 21 int t[maxn]; 22 int SG[maxn]; 23 int vis[maxn]; 24 25 vector<int> G[maxn]; 26 vector<int
> new_G[maxn]; 27 28 //求時間點 29 void bfs() 30 { 31 memset(t, -1, sizeof(t)); 32 queue<int> Q; 33 Q.push(1); 34 t[1]=1; 35 while(!Q.empty()) 36 { 37 int u = Q.front(); Q.pop(); 38 for(int i = 0; i < G[u].size(); i++) 39 { 40 int v = G[u][i]; 41 if(t[v] != -1) continue; 42 t[v] = t[u] + 1; 43 Q.push(v); 44 } 45 } 46 } 47 48 //建新圖 49 void re_build() 50 { 51 for(int i = 1; i <= n; i++) 52 { 53 for(int j = 0; j < G[i].size(); j++) 54 { 55 int v = G[i][j]; 56 if(t[v] == t[i] + 1) 57 new_G[i].push_back(v); 58 } 59 } 60 } 61 62 //求SG 63 void dfs(int u) 64 { 65 if(new_G[u].size() == 0) 66 { 67 SG[u] = 0; 68 return; 69 } 70 for(int i = 0; i < new_G[u].size(); i++) 71 { 72 int v = new_G[u][i]; 73 dfs(v); 74 } 75 76 //求mex,也就是父親結點的SG值 77 for(int i = 0; ;i++) 78 { 79 bool flag = false; 80 for(int j = 0; j < new_G[u].size(); j++) 81 { 82 if(SG[new_G[u][j]] == i) 83 { 84 flag = true; 85 break; 86 } 87 } 88 if(flag == false) 89 { 90 SG[u] = i; 91 break; 92 } 93 } 94 } 95 96 97 int main() 98 { 99 freopen("input.txt","r",stdin); 100 freopen("output.txt","w",stdout); 101 // freopen("in.txt","r",stdin); 102 while(~scanf("%d%d",&n, &m)) 103 { 104 for(int i = 1; i <= n; i++) {G[i].clear(); new_G[i].clear();} 105 106 for(int i = 0; i < m; i++) 107 { 108 int u, v; 109 scanf("%d%d",&u, &v); 110 G[u].push_back(v); 111 G[v].push_back(u); 112 } 113 114 bfs(); 115 re_build(); 116 dfs(1); 117 if(SG[1] == 0) puts("Nikolay"); 118 else puts("Vladimir"); 119 } 120 return 0; 121 }

Gym 101246D Fire in the Country(dfs求SG函數)