zoukankan      html  css  js  c++  java
  • SGU 520 Fire in the Country(博弈+搜索)

    Description

    This summer's heat wave and drought unleashed devastating wildfires all across the Earth. Of course, a tiny country on the island "Yars and Eva" is also affected by this ecological disaster. Thanks to the well-organized actions of rescuers, all the citizens were evacuated to the nearby planets on a spaceship. 

    To save the country, a small fire robot was left on its territory. He managed to extinguish fire in all cities except the capital before running out of liquid. The robot can't extinguish fire anymore, so the country is still in danger at the moment. 

    There are n cities in the country connected by m two-way roads. Each road connects a pair of cities. There is at most one road between any pair of cities. The cities are numbered from 1 to n, with capital having the number 1. 

    The fire spreads very quickly. On the very first day only the capital is on fire. But with every subsequent day, the fire devours all the cities connected by a road with the cities that are already on fire. Once the fire gets to a certain city, this city will continue to stay on fire till the very end. 

    The robot can't extinguish the fire anymore and there are no other means of firefighting left in the country, so obviously the country is going to be burned down to the ground. And you don't have to be a hero and save it. The key thing is that the robot is going to be destroyed by fire as well, and you need to figure out who will actually pay for the loss of government property. 

    Two pilots, Nikolay and Vladimir, are on Earth's natural satellite. They alternately take turns controlling the robot. The pilots alternate each day. Robot's speed is equal to the speed of fire, so the robot can get to the neighboring city in a day. Each pilot does not want the robot to be destroyed on his turn. For such a valuable loss they will have to pay a huge fee to the government. 

    On the first day the robot is located in the capital. Nikolay controls the robot on the first day. Thus, Nikolay controls the robot on the days with odd numbers, and Vladimir controls it on the days with even numbers. Taking turn, a pilot has to move the robot from the current city to any city connected by a road with the current one. If a pilot moves the robot to a city which is on fire, the robot is destroyed. 

    You task is to figure out who will pay the fine for the destroyed robot, assuming both pilots act optimally.

    Input

    The first line of input contains the amount of cities n and the amount of roads m in the country (2 ≤ n ≤ 1000, n-1 ≤ m ≤ 1000). The following m lines contain description of the roads: ab — indices of the cities connected by roads (1 ≤ a ≤ n, 1 ≤ b ≤ na ≠ b). The roads are bidirectional. No pair of cities will be connected by more than one road. There will be a path between any two cities.

    Output

    Output the name of the pilot who will pay the fine, assuming both pilots act optimally (" 
    Nikolay
    " — if it is Nikolay, " 
    Vladimir
    " — if it is Vladimir).
     
    题目大意:有n个点,m条无向边,棋子在点1,一人走一步,只能走到直接关联的点,然后点1着火了,每次从1开始扩散,与着火点直接关联的点都会着火,而且不会灭,谁往火力走谁输。
    思路:先看火的蔓延,每次都会往外扩散,棋子也每次往外走一步。BFS求每个点到1的最短路径,然后棋子每一步都只能走与之直接相连而且最短路比之大1的点。谁走到无路可走谁就输,那么不管怎么走走到某一点的必然是同一个人,到1的最短路径为单数的是对方,复数的是自己。而每一点的后续都是固定的,那么每一点的胜败状态也是固定的(假设两人都足够聪明)。那么考虑任意一个状态,如果是自己走,那么只要有一个下一步是必胜状态,那么这个状态就是必胜状态,否则为必败状态(怎么走都输);如果是对方走,那么对方只要有一个下一步是我的必败状态,这个状态就是我的必败状态,否则为必胜状态(对方怎么走都是我赢)。记录状态的话,时间复杂度就是O(n)。(其实还有更简单的解法不过我就不说了……)
    PS:代码能力不够啊WA了无数次……
     
     1 #include <cstdio>
     2 #include <cstring>
     3 #include <queue>
     4 using namespace std;
     5 
     6 const int MAXN = 1005;
     7 const int MAXE = 2005;
     8 
     9 int n, m, f, ecnt;
    10 int head[MAXN], dis[MAXN];
    11 int to[MAXE], next[MAXE];
    12 
    13 void add_edge(int u, int v) {
    14     to[ecnt] = v; next[ecnt] = head[u]; head[u] = ecnt++;
    15     to[ecnt] = u; next[ecnt] = head[v]; head[v] = ecnt++;
    16 }
    17 
    18 void bfs() {
    19     queue<int> que; que.push(1);
    20     dis[1] = 1;
    21     while(!que.empty()) {
    22         int u = que.front(); que.pop();
    23         for(int p = head[u]; p; p = next[p]) {
    24             int &v = to[p];
    25             if(!dis[v]) {
    26                 dis[v] = dis[u] + 1;
    27                 que.push(v);
    28             }
    29         }
    30     }
    31 }
    32 
    33 int win[MAXN];
    34 
    35 int dfs(int u) {
    36     if(win[u] != -1) return win[u];
    37     for(int p = head[u]; p; p = next[p]) {
    38         int &v = to[p];
    39         if(dis[v] == dis[u] + 1) {
    40             if(dis[u] & 1) {if(dfs(v)) return win[u] = 1;}
    41             else if(!dfs(v)) return win[u] = 0;
    42         }
    43     }
    44     return win[u] = !(dis[u] & 1);
    45 }
    46 
    47 int main() {
    48     scanf("%d%d", &n, &m);
    49     ecnt = 1;
    50     while(m--) {
    51         int u, v;
    52         scanf("%d%d", &u, &v);
    53         add_edge(u, v);
    54     }
    55     bfs();
    56     memset(win, -1, sizeof(win));
    57     if(dfs(1)) puts("Vladimir");
    58     else puts("Nikolay");
    59 }
    View Code
  • 相关阅读:
    Android应用程序执行流程
    Android的架构与Android应用程序启动流程
    Android开发环境使用工具Eclipse IDE工程目录结构
    MySQL 的 crash-safe 原理解析
    vivo 悟空活动中台
    图解 Promise 实现原理(三)—— Promise 原型方法实现
    领域驱动设计(DDD)实践之路(三):如何设计聚合
    深入浅出开源监控系统Prometheus(上)
    你还应该知道的哈希冲突解决策略
    反应式编程 RxJava 设计原理解析
  • 原文地址:https://www.cnblogs.com/oyking/p/3254245.html
Copyright © 2011-2022 走看看