HDU 1317 Bellman-Ford
2015-06-06 00:18
330 查看
题意:玩家从起点房间带有100能量,到达一个房间后能量为到达前和房间能量的和,每个房间可以重复进入,并且注意图为有向图。整个过程持续到玩家到达最后一个房间,或是能量值耗尽。
思路:Bellman-Ford求一遍“最长路”(这里不建议用SPFA,因为对环不好处理)。如果路径中有正环,则检查该环能否到达终点,能则winnable;如果没有环,就判断能否直接到达终点。
思路:Bellman-Ford求一遍“最长路”(这里不建议用SPFA,因为对环不好处理)。如果路径中有正环,则检查该环能否到达终点,能则winnable;如果没有环,就判断能否直接到达终点。
#include<cstdio> #include<algorithm> #include<vector> #include<queue> #include<cstring> #include<iostream> #include<cmath> #include<functional> using namespace std; typedef long long ll; typedef pair<int,int> P; const int maxn = 105; const double eps = 1e-8; const int inf = 1e9; struct IN{ int eng,num; int link[maxn]; }in[maxn]; struct Edge{ int to; int cost; }; int n; vector<Edge> G[maxn]; int dis[maxn]; bool vis[maxn]; void debug(){ for(int i=1;i<=n;i++){ for(int j=0;j<G[i].size();j++) cout<<i<<" "<<G[i][j].to<<" "<<G[i][j].cost<<endl; } } void init(){ for(int i=0;i<maxn;i++) G[i].clear(); } void add_Edge(int from,int to,double cost){ Edge e; e.to = to;e.cost = cost; G[from].push_back(e); } void dfs(int v){ vis[v] = true; int u; for(int i=0;i<G[v].size();i++){ u = G[v][i].to; if(!vis[u]) dfs(u); } } void build(){ for(int i=1;i<=n;i++){ for(int j=0;j<in[i].num;j++){ int v = in[i].link[j]; add_Edge(i,v,in[v].eng); } } } bool spfa(){ for(int i=1;i<=n;i++) dis[i] = -inf; bool have_loop = false; dis[1] = 100; for(int v = 1;v <= n;v++){ for(int i=0;i<G[v].size();i++){ Edge e = G[v][i]; if(dis[e.to] < dis[v] + e.cost && dis[v] + e.cost > 0){ dis[e.to] = dis[v] + e.cost; if(v == n) have_loop = true; } } } for(int v = 1;v <= n;v++){ for(int i=0;i<G[v].size();i++){ Edge e = G[v][i]; if(dis[e.to] < dis[v] + e.cost && dis[v] + e.cost > 0){ memset(vis,0,sizeof(vis)); dfs(v); if(vis ) return true; else break; } } } return dis > 0; } void solve(){ memset(vis,0,sizeof(vis)); dfs(1); if(!vis ){ printf("hopeless\n"); return; } if(spfa()) printf("winnable\n"); else printf("hopeless\n"); } int main(){ while(~scanf("%d",&n)){ if(n == -1) break; init(); for(int i=1;i<=n;i++){ scanf("%d%d",&in[i].eng,&in[i].num); for(int j=0;j<in[i].num;j++){ scanf("%d",&in[i].link[j]); } } build(); solve(); } return 0; }
相关文章推荐
- BZOJ1257 [CQOI2007]余数之和sum(枚举商)
- Matlab图像处理系列3———空间域锐化滤波器
- file_get_contents的深入
- 编译错误:undefined reference to `clock_gettime'
- 不相交集合的数据结构
- HDU 2002 计算球体积
- ios开发----应用数据存储的常用方法之plist存取方法
- C++函数可变参数实现原理探究——以实现printf为例
- iOS开发数据持久化技术02——plist介绍
- Apache与php在Windows下配置安装
- 我火狐浏览器的好多TMP的临时文件都跑桌面来了,怎么修改存放地方啊?
- 高效位运算 __builtin_系列函数
- leetcode--Min Stack
- Android自定义控件
- linux调度器源码分析 - 初始化(二)
- linux 怎样查找某个文件或目录属于哪个分区的。
- Java interface 做函数参数
- Java for LeetCode 171 Excel Sheet Column Number
- 对象与类的认识
- File 随笔 ( 1 )