Gym 101246DFire in the Country(dfs求SG函数)
Posted 谦谦君子,陌上其华
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Gym 101246DFire in the Country(dfs求SG函数)相关的知识,希望对你有一定的参考价值。
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 101246DFire in the Country(dfs求SG函数)的主要内容,如果未能解决你的问题,请参考以下文章
Gym 101246H``North-East''(LIS)
gym102222KVertex Covers(高维前缀和,meet in the middle)
Gym102156J The Good, the Bad and the Ugly
2017年Nature文章“Millions of online book co-purchases reveal partisan differences in the consumption of
Android记录我遇到的坑The minCompileSdk (31) specified in a dependency‘s AAR metadata (META-INF/co