Written by razrlele
	   23:29                      February 14, 2015 
这个题最关键的部分就是对于环的处理。
先记录下每个点是否已经访问,并且到达那个点时候的能量值,然后碰见环再次访问已经访问过的点的时候,如果能量大于之前,就说明通过这个环能量可以增长到无限大,然后再开启另一个DFS探测环是否有到达终点的路线,如果有那么直接就是winnable,否则的话直接放弃这个环。
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 | /********************************************************     * File Name: uvaoj10557.cpp     * Author: razrLeLe     * Mail: razrlele@gmail.com     * Homepage: https://yueyu.io     * Created Time: Sat 14 Feb 2015 09:23:00 PM CST  ******************************************************/ #include "vector" #include "set" #include "deque" #include "queue" #include "algorithm" #include "functional" #include "iostream" #include "cstdio" #include "cmath" #include "cstdlib" #include "string" #include "cstring" #include "string.h" #include "map" #include "cctype" #include "list" #include "stack" using namespace std; #define INF 0x3f3f3f3f #define LOCAL const int maxn = 110; int grid[maxn][maxn]; int energy[maxn]; int route[maxn]; int roomnum; int vis[maxn]; bool reachable, winnable; void DFS_TEST(int a) {     if(a == roomnum)     reachable = true;     if(reachable)     return ;     vis[a] = 1;     for(int i = 1; i <= roomnum; i++)     if(grid[a][i] && vis[i] == -1)     DFS_TEST(i);     return ; } void DFS(int num, int e) {     if(e+energy[num] <= 0 || e+energy[num] <= route[num] || winnable)     return;     e += energy[num];     if(num == roomnum)     {         winnable = true;         return ;     }     if(route[num] == -1)     {         route[num] = e;     }     else if(e > route[num])     {         memset(vis, -1, sizeof(vis));         reachable = false;         DFS_TEST(num);         if(reachable)         winnable = true;         return ;     }     for(int i = 1; i <= roomnum; i++)     if(grid[num][i])     DFS(i, e);     return ; } int main() { #ifdef LOCAL     freopen("/home/razrlele/build/data.txt", "r", stdin);     freopen("/home/razrlele/build/out.txt", "w", stdout); #endif     while(scanf("%d", &roomnum) && roomnum >= 0)     {         memset(grid, 0, sizeof(grid));         memset(route, -1, sizeof(route));        for(int i = 1; i <= roomnum; i++)          {             int doornum, door;             scanf("%d %d", &energy[i], &doornum);             while(doornum--)             {                scanf("%d", &door);                grid[i][door] = 1;             }         }         winnable = false;         DFS(1, 100);         if(winnable)         printf("winnable\n");         else         printf("hopeless\n");     }     return 0; } |