UVALive - 4618 Wormholes(负环)
来源:互联网 发布:网络诈骗安全选择题 编辑:程序博客网 时间:2024/06/05 14:52
题目大意:给出出发点和终点和m个虫洞(虫洞的出发点,终点,生成时间和花费时间),问从起点到终点花费的最小时间
解题思路:关键是有负环,所以直接跑最短路算法的话会TLE,所以负环要处理一下
但是这个负环又不是负环,因为负环到一定程度的话,就会消失。
比如,到达时间小于虫洞的生成时间,那么负环就消失了,也就是说,负环内的点满足的最优情况就是到达时间刚好等于生成时间
所以,先找出负环,接着判断一下这个负环内的能节省的最多时间,然后将所有点都减去那个时间,那么负环就消失了
具体看代码
#include <cstdio>#include <cstring>#include <cmath>#include <algorithm>using namespace std;#define N 110#define INF 0x3f3f3f3fstruct Point{ int x, y, z;}s1, s2;struct wormhole{ Point s, t; int start, cost;}W[N];int n, source, sink;int dis[N][N];int distance(int i, int j) { int x = W[i].t.x - W[j].s.x; int y = W[i].t.y - W[j].s.y; int z = W[i].t.z - W[j].s.z; return ceil(sqrt(1.0 * x * x + 1.0 * y * y + 1.0 * z * z));}void init() { scanf("%d%d%d%d%d%d%d", &s1.x, &s1.y, &s1.z, &s2.x, &s2.y, &s2.z, &n); source = 0; sink = n + 1; W[0].s = s1; W[0].t = s1; W[0].start = -INF; W[0].cost = 0; W[sink].s = s2; W[sink].t = s2; W[sink].start =-INF; W[sink].cost = 0; for (int i = 1; i <= n; i++) scanf("%d%d%d%d%d%d%d%d", &W[i].s.x, &W[i].s.y, &W[i].s.z, &W[i].t.x, &W[i].t.y, &W[i].t.z, &W[i].start, &W[i].cost); //dis[i][j]表示从第i个虫洞的终点走到第j个虫洞的出发点的时间 for (int i = 0; i <= sink; i++) for (int j = 0; j <= sink; j++) dis[i][j] = distance(i, j);}int pre[N], d[N];void solve() { for (int i = 0; i <= sink; i++) { d[i] = INF; pre[i] = -1; } d[source] = 0; while (1) { int tmp; bool flag = false; //找最短路 for (int i = 0; i <= sink; i++) for (int j = 0; j <= sink; j++) { tmp = max(d[i] + dis[i][j], W[j].start) + W[j].cost; if (tmp < d[j]) { d[j] = tmp; pre[j] = i; flag = true; } } //不用更新了 if (!flag) { printf("%d\n", d[sink]); return ; } for (int i = 0; i <= sink; i++) { int k = i; //判断有没有环 for (int j = 0; j <= sink && k != -1; j++) k = pre[k]; if (k == -1) continue; //找出更新的值,破除这个负环,更新的值就是到达起点的值和生成时间的差的最小值,因为在负环内可以等待到生成时间 int Min = d[pre[k]] + dis[pre[k]][k] - W[k].start; for (int j = pre[k]; j != k; j = pre[j]) Min = min(d[pre[j]] + dis[pre[j]][j] - W[j].start, Min); //如果不存在负环了 if (Min <= 0) continue; //更新负环内的点的距离,破解负环 d[k] -= Min; for (int j = pre[k]; j != k; j = pre[j]) d[j] -= Min; } }}int main() { int test; scanf("%d", &test); while (test--) { init(); solve(); } return 0;}
1 1
- UVALive - 4618 Wormholes(负环)
- UVALive - 4618 Wormholes(负环)
- Wormholes (判断负环)
- UVA - 558 Wormholes 负环
- Wormholes(spfa判断负环)
- [POJ3259]Wormholes(负环)
- POJ:3259 Wormholes(SPFA判断负环)
- POJ3259 Wormholes 【SPFA判断负环】
- Wormholes - UVa 558 spfa判断负环
- POJ3259 Wormholes(Bellman-ford 负环)
- 【POJ3259】【Wormholes】【负环判断】【bell-ford】
- POJ 3259 Wormholes 【SPFA 判断负环】
- POJ 3259 Wormholes 判断负环
- poj 3259 Wormholes 【判断负环】
- poj 3259 Wormholes 【SPFA&&判断负环】
- POJ 3259:Wormholes bellman_ford判定负环
- POJ3259----Wormholes(SPFA判断负环)
- Poj 3259 Wormholes【spfa 负环判断】
- 树懒_移动开学笔记_day19_高级UI编程思路
- 七夕与Gulp的第一次!
- 数据结构List
- 树懒_移动开学笔记_day20_ui_Toast_dialog编程思路
- 数据结构学习笔记之线性结构栈
- UVALive - 4618 Wormholes(负环)
- 1064. Complete Binary Search Tree (30)
- getClass(),class属性和getName()解析getGenericSuperclass
- 树懒_移动开学笔记_day21_自定义通知_存储思路
- [C++]学习札记2015-08-21
- VS2015 scanf 函数报错 error C4996: 'scanf'
- 树懒_移动开学笔记_day22_pull解析与SQLite
- 关于离散数学
- 构造函数为什么不能是虚函数