Gym 101246D Fire in the Country(dfs求SG函數)
阿新 • • 發佈:2017-06-23
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函數)