• hdu-1317 XYZZY---Floyd判连通+bellman最短路


    题目链接:

    http://acm.hdu.edu.cn/showproblem.php?pid=1317

    题目大意:

    题意:有n个房间(n<=100),每个房间有一个点权(第1号房间和第n号房间权值均为0),到达该房间时会自动获得该点权(可能为负权)。给出一些无向边。有一个人,初始有能量值100,初始位置是第1号房间,要走到第n号房间,且路途中不得使身上能量值小于或等于0。能到达第n个房间就算赢,问能否赢。

    解题思路:

    这里最坑的是第一号房间可能和最后一个房间连通不了。所以首先得判断连通性,再Bellman求最短路。

    如果floyd判断房间1和房间n不连通,直接输出失败

    如果在第n次还在松弛并且松弛的点可以到达终点n,说明存在正环且该正环能到达n,此时一定是成功的。

    如果到达n的时候能量值为正数则成功,为0或者负数则失败

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 const int maxn = 10000 + 10;
     5 const int INF = 0x3f3f3f3f;
     6 struct edge
     7 {
     8     int u, v, w;
     9     edge(){}
    10     edge(int u, int v, int w):u(u), v(v), w(w){}
    11 };
    12 edge e[maxn];
    13 bool Map[105][105];
    14 int num[105], n, d[maxn], tot;
    15 void addedge(int u, int v, int w)
    16 {
    17     e[tot++] = edge(u, v, w);
    18 }
    19 void floyd()//判断连通性
    20 {
    21     for(int k = 1; k <=n; k++)
    22     {
    23         for(int i = 1; i <= n; i++)
    24         {
    25             for(int j = 1; j <= n; j++)
    26             {
    27                 Map[i][j] |= (Map[i][k]&Map[k][j]);
    28             }
    29         }
    30     }
    31 }
    32 bool Bellman(int u)
    33 {
    34     memset(d, -INF, sizeof(d));
    35     d[u] = 100;
    36     for(int i = 0; i < n; i++)
    37     {
    38         for(int j = 0; j < tot; j++)
    39         {
    40             int u = e[j].u, v = e[j].v, w = e[j].w;
    41             if(d[u] + w > d[v] && d[u] > 0)//d[u]>0说明只有能量为正的点才可以对其相邻的边进行松弛
    42             {
    43                 d[v] = d[u] + w;
    44                 if(i == n - 1 && Map[v][n])
    45                 //i==n-1说明第n次迭代还在松弛,说明存在正环
    46                 //Map[v][n]=1说明松弛的点可以到达终点(这里改成Map[u][n]也是一样的,因为这两个的值是一样的,因为存在边<u, v>)
    47                 //满足上面两个条件说明存在一个正环,且该环可以到达终点
    48                 //可以一直在正环中运动使得能量值无穷大,最后就一定能到终点
    49                     return 1;
    50             }
    51         }
    52     }
    53     return d[n] > 0;
    54 }
    55 int main()
    56 {
    57     while(cin >> n && n != -1)
    58     {
    59         int t, x;
    60         tot = 0;
    61         memset(Map, 0, sizeof(Map));
    62         for(int i = 1; i <= n; i++)
    63         {
    64             cin >> num[i];
    65             cin >> t;
    66             while(t--)
    67             {
    68                 cin >> x;
    69                 Map[i][x] = 1;
    70             }
    71         }
    72         for(int u = 1; u <= n; u++)
    73         {
    74             for(int v = 1; v <= n; v++)
    75             {
    76                 if(Map[u][v])addedge(u, v, num[v]);
    77             }
    78         }
    79         floyd();
    80         if(!Map[1][n])cout<<"hopeless"<<endl;//1-n直接不连通
    81         else if(Bellman(1))cout<<"winnable"<<endl;
    82         else cout<<"hopeless"<<endl;
    83     }
    84     return 0;
    85 }
  • 相关阅读:
    【项目】项目188
    【项目】项目190
    【项目】项目192
    【项目】项目189
    【项目】项目185
    SpringBoot统一Api接口返回格式
    MySQL判断库、表、列是否存在
    java.net.SocketException: Connection reset by peer: socket write error
    NOI Online 2022 一游
    寒假 杂题题解
  • 原文地址:https://www.cnblogs.com/fzl194/p/8909894.html
Copyright © 2020-2023  润新知