首页 > 代码库 > Gym 101246D Fire in the Country(dfs求SG函数)

Gym 101246D Fire 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 101246D Fire in the Country(dfs求SG函数)