题意:给一个有向图,每个点有一个权值,从1个点出发,初始能量有100,每到达新的点,能量就会加上那个点的权值,当能量大于0时才能继续走,可以多次进入同一点。问能否到达目标点

思路:如果没正权环,则直接优先队列bfs模拟走的过程即可,因为先到不会比后到的能量少,那过程其实就和dijkstra差不多,但根据题目的意思,是可能存在正权环的,所以dijkstra行不通,于是考虑spfa。一旦某个点入队了n次,就可判定这个点在正权环上,通过在正权环上不断走来获得无限的能量,于是将这个点的能量值设为无穷大,并让它再入队一次后丢弃这个点(因为能量值变为了无穷大,需要用它来更新邻点,更新完了它就没有存在的意义了),同时判断这个点是否与目标点连通,如果连通,那么毫无疑问,目标点肯定可以顺利到达。

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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#include <map>
#include <set>
#include <cmath>
#include <ctime>
#include <deque>
#include <queue>
#include <vector>
#include <cstdio>
#include <string>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
 
using namespace std;
 
#define X                   first
#define Y                   second
#define pb                  push_back
#define mp                  make_pair
#define all(a)              (a).begin(), (a).end()
#define fillchar(a, x)      memset(a, x, sizeof(a))
 
typedef long long ll;
typedef pair<intint> pii;
typedef unsigned long long ull;
 
#ifndef ONLINE_JUDGE
void RI(vector<int>&a,int n){a.resize(n);for(int i=0;i<n;i++)scanf("%d",&a[i]);}
void RI(){}void RI(int&X){scanf("%d",&X);}template<typename...R>
void RI(int&f,R&...r){RI(f);RI(r...);}void RI(int*p,int*q){int d=p<q?1:-1;
while(p!=q){scanf("%d",p);p+=d;}}void print(){cout<<endl;}template<typename T>
void print(const T t){cout<<t<<endl;}template<typename F,typename...R>
void print(const F f,const R...r){cout<<f<<", ";print(r...);}template<typename T>
void print(T*p, T*q){int d=p<q?1:-1;while(p!=q){cout<<*p<<", ";p+=d;}cout<<endl;}
#endif
template<typename T>bool umax(T&a, const T&b){return b<=a?false:(a=b,true);}
template<typename T>bool umin(T&a, const T&b){return b>=a?false:(a=b,true);}
template<typename T>
void V2A(T a[],const vector<T>&b){for(int i=0;i<b.size();i++)a[i]=b[i];}
template<typename T>
void A2V(vector<T>&a,const T b[]){for(int i=0;i<a.size();i++)a[i]=b[i];}
 
const double PI = acos(-1.0);
const int INF = 1e9 + 7;
 
/* -------------------------------------------------------------------------------- */
 
const int maxn = 107;
 
struct Graph {
    vector<vector<int> > G;
    void clear() { G.clear(); }
    void resize(int n) { G.resize(n + 2); }
    void add(int u, int v) { G[u].push_back(v); }
    vector<int> & operator [] (int u) { return G[u]; }
};
Graph G;
 
bool vis[maxn], flag[maxn];
int n;
int cnt[maxn], d[maxn], p[maxn];
 
bool dfs(int s, int t) {
    if (s == t) return true;
    vis[s] = true;
    for (int i = 0; i < G[s].size(); i ++) {
        int v = G[s][i];
        if (!vis[v]) if (dfs(v, t)) return true;
    }
    return false;
}
 
bool relax(int u, int v) {
    if (d[u] + p[v] > d[v]) {
        d[v] = d[u] + p[v];
        return true;
    }
    return false;
}
 
bool work() {
    queue<int> Q;
    Q.push(1);
    fillchar(d, 0);
    fillchar(flag, 0);
    fillchar(cnt, 0);
    d[1] = 100;
    flag[1] = true;
    while (!Q.empty()) {
        int u = Q.front(); Q.pop();
        flag[u] = false;
        if (u == n) return true;
        if (d[u] >= 1e8) {
            fillchar(vis, 0);
            if (dfs(u, n)) return true;
        }
        int sz = G[u].size();
        for (int i = 0; i < sz; i ++) {
            int v = G[u][i];
            if (relax(u, v)) {
                if (!flag[v]) {
                    flag[v] = true;
                    if (cnt[v] > n) continue;
                    if (cnt[v] == n) d[v] = INF;
                    Q.push(v);
                    cnt[v] ++;
                }
            }
        }
    }
    return false;
}
int main() {
#ifndef ONLINE_JUDGE
    freopen("in.txt""r", stdin);
    //freopen("out.txt", "w", stdout);
#endif // ONLINE_JUDGE
    int m, v;
    while (cin >> n, ~n) {
        G.clear();
        G.resize(n);
        for (int i = 1; i <= n; i ++) {
            scanf("%d%d", p + i, &m);
            for (int j = 0; j < m; j ++) {
                scanf("%d", &v);
                G.add(i, v);
            }
        }
        fillchar(vis, 0);
        if (!dfs(1, n)) puts("hopeless");
        else puts(work()? "winnable" "hopeless");
    }
    return 0;
}

[hdu1317]spfa的更多相关文章

  1. 【BZOJ-3627】路径规划 分层图 + Dijkstra + spfa

    3627: [JLOI2014]路径规划 Time Limit: 30 Sec  Memory Limit: 128 MBSubmit: 186  Solved: 70[Submit][Status] ...

  2. POJ 2387 Til the Cows Come Home(最短路 Dijkstra/spfa)

    传送门 Til the Cows Come Home Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 46727   Acce ...

  3. sgu 240 Runaway (spfa)

    题意:N点M边的无向图,边上有线性不下降的温度,给固定入口S,有E个出口.逃出去,使最大承受温度最小.输出该温度,若该温度超过H,输出-1. 羞涩的题意 显然N*H的复杂度dp[n][h]表示到达n最 ...

  4. spfa模板

    通过stl的queue实现的spfa(vector实现邻接表存图) 本模板没有考虑存在两点不连通的情况 如果需要判断则需要用到并查集或者遍历整个邻接表 #include<iostream> ...

  5. SPFA

    SPFA算法用来求单源最短路.可以处理任何有解的情况. 先建一个数组\(dist_x = 起点到x的最短路长度\),当\(x=起点\)时为0,当x和起点不通时为INF(本题中为\(2^31-1\)). ...

  6. BZOJ2763 [JLOI2011]飞行路线(SPFA + DP)

    题目 Source http://www.lydsy.com/JudgeOnline/problem.php?id=2763 Description Alice和Bob现在要乘飞机旅行,他们选择了一家 ...

  7. bzoj3380: [Usaco2004 Open]Cave Cows 1 洞穴里的牛之一(spfa+状压DP)

    数据最多14个有宝藏的地方,所以可以想到用状压dp 可以先预处理出每个i到j的路径中最小权值的最大值dis[i][j] 本来想用Floyd写,无奈太弱调不出来..后来改用spfa 然后进行dp,这基本 ...

  8. bzoj 1179[Apio2009]Atm (tarjan+spfa)

    题目 输入 第一行包含两个整数N.M.N表示路口的个数,M表示道路条数.接下来M行,每行两个整数,这两个整数都在1到N之间,第i+1行的两个整数表示第i条道路的起点和终点的路口编号.接下来N行,每行一 ...

  9. codevs 1021 玛丽卡(spfa)

    题目描述 Description 麦克找了个新女朋友,玛丽卡对他非常恼火并伺机报复. 因为她和他们不住在同一个城市,因此她开始准备她的长途旅行. 在这个国家中每两个城市之间最多只有一条路相通,并且我们 ...

随机推荐

  1. 架构师修炼之微服务部署 - Docker简介

    Docker简介 Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器或Windows 机器上,也可以实现虚拟化,容器是 ...

  2. jmeter5.1.1 生成html报告

    1.首先需要准备好 .jmx 脚本 2.修改jmeter.properties文件(把注解去掉,报告中才能展示所需信息) jmeter.save.saveservice.output_format=x ...

  3. iOS中点击事件失效的解决办法

    解决办法有 2种可供选择: 将目标​元素换成 <a> 或者 button 等可点击的​元素 ​给​目标元素加一条样式规则 cursor : pointer;

  4. 《并发编程的艺术》阅读笔记之Lock与AQS

    Lock接口 在jdk1.5之后,并发包下新增了一个lock接口,lock接口定义了锁的获取,锁的释放,等方法,需要用户手动设置.与关键字不同的是,lock具有可操作性,比如,可以中断线程,设置超时时 ...

  5. Apache漏洞利用与安全加固实例分析

    Apache 作为Web应用的载体,一旦出现安全问题,那么运行在其上的Web应用的安全也无法得到保障,所以,研究Apache的漏洞与安全性非常有意义.本文将结合实例来谈谈针对Apache的漏洞利用和安 ...

  6. TIME_WAIT的危害与避免

    time-wait的产生: 在TCP连接中四次挥手关闭连接时,主动关闭连接的一方(上图中时Client)会在发送最后一条ACK报文后维持一段时长2MSL(MSL指的是数据包在网络中的最大生存时间)的等 ...

  7. 【Linux网络基础】TCP/IP 协议簇(各个常见协议介绍)

    一.应用层协议 1. FTP   协议所在层次:应用层协议 名称:FTP协议 协议端口:20,21 协议说明: FTP(File Transfer Protocol,文件传输协议)是TCP/IP协议组 ...

  8. ExtJS2.0实用简明教程 - Form布局

            Form布局由类Ext.layout.FormLayout定义,名称为form,是一种专门用于管理表单中输入字段的布局,这种布局主要用于在程序中创建表单字段或表单元素等使用.   看下 ...

  9. 数学--数论--HDU-2698 Maximum Multiple(规律)

    Given an integer nn, Chiaki would like to find three positive integers xx, yy and zzsuch that: n=x+y ...

  10. 概率dp部分题目

    记录一些比较水不值得单独写一篇blog的概率dp题目 bzoj3036 绿豆蛙的归宿 Description 随着新版百度空间的下线,Blog宠物绿豆蛙完成了它的使命,去寻找它新的归宿. 给出一个有向 ...