zoukankan      html  css  js  c++  java
  • [HDOJ1317]XYZZY(SPFA, floyd)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1317

    题意:给一张有向的点权图,一个人在起点有初始值100,这个人从一个点到另一个点时要加上对应目标点的权值。问有没有一条路径使得这个人的当前值都是正数的前提下,到达终点。

    由于问能不能,考虑一个情况就是有正数环的情况,假如这个环可以到达终点,那么无论如何都可以到达终点。这个可达的状态可以通过floyd来求传递闭包得出。因为相当于是求最长路,那么负环就不必要考虑了。

    所以做法就是先floyd求出传递闭包,在基础上做spfa,更新两个点之间的时候要考虑是否可达。

     1 #include <cstdio>
     2 #include <queue>
     3 #include <vector>
     4 #include <cstring>
     5 #include <iostream>
     6 #include <algorithm>
     7 using namespace std;
     8 typedef pair<int, int> pii;
     9 
    10 const int maxn = 110;
    11 const int maxm = 10100;
    12 const int inf = 0x7f7f7f;
    13 const int nl = 100;
    14 vector<pii> G[maxn];
    15 bool dp[maxn][maxn];
    16 int vcnt[maxn];
    17 int d[maxn];
    18 queue<int> q;
    19 int n, m;
    20 
    21 void floyd() {
    22     for(int k = 1; k <= n; k++) {
    23         for(int i = 1; i <= n; i++) {
    24             for(int j = 1; j <= n; j++) {
    25                 if(dp[i][k] && dp[k][j]) {
    26                     dp[i][j] = 1;
    27                 }
    28             }
    29         }
    30     }
    31 }
    32 
    33 bool spfa(int s) {
    34     memset(vcnt, 0, sizeof(vcnt));
    35     for(int i = 1; i <= n; i++) d[i] = -inf;
    36     while(!q.empty()) q.pop();
    37     q.push(s); d[s] = 100;
    38     while(!q.empty()) {
    39         int u = q.front(); q.pop();
    40         if(vcnt[u] > nl) return dp[u][n];
    41         for(int i = 0; i < G[u].size(); i++) {
    42             int v = G[u][i].first, w = G[u][i].second;
    43             if(dp[u][v] && d[v] < d[u] + w && d[u] + w > 0) {
    44                 d[v] = d[u] + w;
    45                 vcnt[v]++;
    46                 q.push(v);
    47             }
    48         }
    49     }
    50     return d[n] > 0;
    51 }
    52 
    53 int main() {
    54     // freopen("in", "r", stdin);
    55     int v, w, m;
    56     while(~scanf("%d",&n) && ~n) {
    57         memset(dp, 0, sizeof(dp));
    58         for(int i = 1; i <= n; i++) {
    59             G[i].clear();
    60         }
    61         for(int u = 1; u <= n; u++) {
    62             scanf("%d %d", &w, &m);
    63             while(m--) {
    64                 scanf("%d", &v);
    65                 dp[u][v] = 1;
    66                 G[u].push_back(pii(v, w));
    67             }
    68         }
    69         floyd();
    70         if(dp[1][n]) {
    71             if(spfa(1)) puts("winnable");
    72             else puts("hopeless");
    73         }
    74         else puts("hopeless");
    75         // for(int i = 1; i <= n; i++) printf("%d ", d[i]);
    76         // printf("
    ");
    77     }
    78     return 0;
    79 }
  • 相关阅读:
    Codeforces Round #394 (Div. 2) A. Dasha and Stairs
    HDU 1410 PK武林盟主
    HDU 3362 Fix(状压dp)
    P678-vect2.cpp
    Qt5获取本机网络信息
    Qt5标准文件对话框类
    nRF52832无法加载协议栈文件
    Debug记录(1)
    大小端模式
    nRF52832的SAADC
  • 原文地址:https://www.cnblogs.com/kirai/p/5871967.html
Copyright © 2011-2022 走看看