zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    CSUFT 1002 Robot Navigation
    CSUFT 1003 All Your Base
    Uva 1599 最佳路径
    Uva 10129 单词
    欧拉回路
    Uva 10305 给任务排序
    uva 816 Abbott的复仇
    Uva 1103 古代象形文字
    Uva 10118 免费糖果
    Uva 725 除法
  • 原文地址:https://www.cnblogs.com/zyb993963526/p/7071599.html
Copyright © 2011-2022 走看看