POJ 3259 http://poj.org/problem?id=3259

题意:

农夫 FJ 有 N 块田地【编号 1...n】 (1<=N<=500)

田地间有 M 条路径 【双向】(1<= M <= 2500)

同时有 W 个孔洞,可以回到以前的一个时间点【单向】(1<= W <=200)

问:FJ 是否能在田地中遇到以前的自己

算法:bellman_ford 判断是否有负环

思路:

田地间的双向路径加边,权值为正

孔洞间的单向路径加边,权值为负【可以回到以前】

判断有向图是否存在负环

因为如果存在了负数环,时间就会不停的减少,

那么 FJ 就可以回到以前更远的地方,肯定能遇到以前的自己的

bellman_ford

  1. #ifndef ONLINE_JUDGE
  2. #pragma warning(disalbe : 4996)
  3. #endif
  4. #include<iostream>
  5. #include<algorithm>
  6. #include<cstdio>
  7. #include<cstring>
  8. using namespace std;
  9. const int maxn = 510;
  10. const int maxw = 2500 * 2 + 200 + 10;
  11. const int inf = 10000;
  12. int d[maxn];
  13. int n, m;
  14. struct Edge {
  15. int u, v;
  16. int t;
  17. }edge[maxw];
  18. bool bellman_ford() {
  19. for (int i = 1; i <= n; ++i) d[i] = inf;
  20. d[1] = 0;//起点定为0
  21. for (int i = 1; i < n; ++i) {
  22. bool flag = true;
  23. for (int j = 0; j < m; ++j) {
  24. int u = edge[j].u;
  25. int v = edge[j].v;
  26. int t = edge[j].t;
  27. if (d[v] > d[u] + t) {//松弛操作
  28. d[v] = d[u] + t;
  29. flag = false;
  30. }
  31. }
  32. if (flag) return false;//如果当前轮不能松弛,直接判断没有负数环
  33. }
  34. for (int i = 0; i < m; ++i)
  35. if (d[edge[i].v] > d[edge[i].u] + edge[i].t)
  36. return true;//如果仍然能够松弛则存在负环
  37. return false;
  38. }
  39. int main() {
  40. #ifndef ONLINE_JUDGE
  41. freopen("in.txt", "r", stdin);
  42. freopen("out.txt", "w", stdout);
  43. #endif // !ONLINE_JUDGE
  44. int T;
  45. int M, W;
  46. scanf("%d", &T);
  47. while (T--)
  48. {
  49. scanf("%d%d%d", &n, &M, &W);
  50. m = 0;
  51. int u, v, t;
  52. for (int i = 1; i <= M; i++) //田地间的大路,加双边
  53. {
  54. scanf("%d%d%d", &u, &v, &t);
  55. edge[m].u = u;
  56. edge[m].v = v;
  57. edge[m++].t = t;
  58. edge[m].u = v;
  59. edge[m].v = u;
  60. edge[m++].t = t;
  61. }
  62. for (int i = 1; i <= W; i++) //孔洞,加单边
  63. {
  64. scanf("%d%d%d", &u, &v, &t);
  65. edge[m].u = u;
  66. edge[m].v = v;
  67. edge[m++].t = -t;
  68. }
  69. if (bellman_ford()) printf("YES\n"); //存在负数环
  70. else printf("NO\n");
  71. }
  72. #ifndef ONLINE_JUDGE
  73. fclose(stdin);
  74. fclose(stdout);
  75. system("out.txt");
  76. #endif // !ONLINE_JUDGE
  77. return 0;
  78. }

Floyd

  1. #include<iostream>
  2. #include<cstring>
  3. #include<queue>
  4. #include<algorithm>
  5. #include<cmath>
  6. using namespace std;
  7. int n, m, W;//教室、普通走廊、回溯
  8. const int inf = 0x3f3f3f3f, maxn = 510;
  9. int g[maxn][maxn];
  10. bool floyd() {
  11. for (int k = 1; k <= n; ++k)
  12. for (int i = 1; i <= n; ++i) {
  13. for (int j = 1; j <= n; ++j)
  14. if (g[i][j] > g[i][k] + g[k][j])
  15. g[i][j] = g[i][k] + g[k][j];
  16. if (g[i][i] < 0)return true;//存在负环
  17. }
  18. return false;
  19. }
  20. int main() {
  21. //freopen("in.txt","r",stdin);
  22. ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
  23. int t; cin >> t; while (t--) {
  24. cin >> n >> m >> W;
  25. for (int i = 1; i <= n; ++i)
  26. for (int j = 1; j <= n; ++j)
  27. g[i][j] = inf;
  28. for (int i = 0; i <= n; ++i)g[i][i] = 0;
  29. int u, v, w;
  30. for (int i = 0; i < m; ++i)
  31. cin >> u >> v >> w, g[u][v] = g[v][u] = min(g[u][v],w);
  32. for (int i = 0; i < W; ++i)
  33. cin >> u >> v >> w, g[u][v] = -w;
  34. cout << (floyd() ? "YES" : "NO" )<< endl;
  35. }
  36. }

SPFA

  1. //kuangbin 的板子确实挺漂亮的
  2. #include <cstdio>
  3. #include <cmath>
  4. #include <cstring>
  5. #include <algorithm>
  6. #include <queue>
  7. using namespace std;
  8. typedef long long ll;
  9. int n;
  10. const int MAXN = 505, INF = 0x3f3f3f3f;
  11. struct Edge {
  12. int v;
  13. int cost;
  14. Edge(int _v = 0, int _cost = 0) : v(_v), cost(_cost) {}
  15. };
  16. vector<Edge> E[MAXN];
  17. void addedge(int u, int v, int w) {
  18. E[u].push_back(Edge(v, w));
  19. }
  20. bool vis[MAXN];
  21. int cnt[MAXN];
  22. int dist[MAXN];
  23. bool SPFA(int start) {
  24. memset(vis, false, sizeof vis);
  25. memset(cnt, 0, sizeof cnt);
  26. memset(dist, INF, sizeof dist);
  27. queue<int> que;
  28. que.push(start);
  29. ++cnt[start];
  30. dist[start] = 0;
  31. while (!que.empty()) {
  32. int u = que.front(); que.pop();
  33. vis[u] = false;
  34. for (int i = 0; i < E[u].size(); ++i) {
  35. int v = E[u][i].v;
  36. if (dist[v] > dist[u] + E[u][i].cost) {
  37. dist[v] = dist[u] + E[u][i].cost;
  38. if (!vis[v]) {
  39. vis[v] = true;
  40. que.push(v);
  41. if (++cnt[v] > n) return true;
  42. }
  43. }
  44. }
  45. }
  46. return false;
  47. }
  48. int main() {
  49. int f, m, W;
  50. scanf("%d", &f);
  51. while (f--) {
  52. scanf("%d%d%d", &n, &m, &W);
  53. int u, v, w;
  54. for (int i = 0; i < m; ++i) {
  55. scanf("%d%d%d", &u, &v, &w);
  56. addedge(u, v, w);
  57. addedge(v, u, w);
  58. }
  59. for (int i = 0; i < W; ++i) {
  60. scanf("%d%d%d", &u, &v, &w);
  61. addedge(u, v, -w);
  62. }
  63. printf("%s\n", SPFA(1) ? "YES" : "NO");
  64. for (int i = 1; i <= n; ++i)
  65. E[i].clear();
  66. }
  67. return 0;
  68. }

三种方法AC以后发现BF竟然时间最短

POJ 3259 Wormholes(bellman_ford、Floyd、SPFA判断负环)的更多相关文章

  1. 解题报告:poj 3259 Wormholes(入门spfa判断负环)

    Description While exploring his many farms, Farmer John has discovered a number of amazing wormholes ...

  2. POJ 3259 Wormholes(最短路径,求负环)

    POJ 3259 Wormholes(最短路径,求负环) Description While exploring his many farms, Farmer John has discovered ...

  3. POJ 3259 Wormholes【最短路/SPFA判断负环模板】

    农夫约翰在探索他的许多农场,发现了一些惊人的虫洞.虫洞是很奇特的,因为它是一个单向通道,可让你进入虫洞的前达到目的地!他的N(1≤N≤500)个农场被编号为1..N,之间有M(1≤M≤2500)条路径 ...

  4. POJ 3259 Wormholes ( SPFA判断负环 && 思维 )

    题意 : 给出 N 个点,以及 M 条双向路,每一条路的权值代表你在这条路上到达终点需要那么时间,接下来给出 W 个虫洞,虫洞给出的形式为 A B C 代表能将你从 A 送到 B 点,并且回到 C 个 ...

  5. Wormholes POJ - 3259 spfa判断负环

    //判断负环 dist初始化为正无穷 //正环 负无穷 #include<iostream> #include<cstring> #include<queue> # ...

  6. POJ3259 Wormholes(SPFA判断负环)

    Description While exploring his many farms, Farmer John has discovered a number of amazing wormholes ...

  7. Wormholes---poj3259(最短路 spfa 判断负环 模板)

    题目链接:http://poj.org/problem?id=3259 题意是问是否能通过虫洞回到过去: 虫洞是一条单向路,不但会把你传送到目的地,而且时间会倒退Ts. 我们把虫洞看成是一条负权路,问 ...

  8. [APIO2017]商旅——分数优化+floyd+SPFA判负环+二分答案

    题目链接: [APIO2017]商旅 枚举任意两个点$(s,t)$,求出在$s$买入一个物品并在$t$卖出的最大收益. 新建一条从$s$到$t$的边,边权为最大收益,长度为原图从$s$到$t$的最短路 ...

  9. spfa判断负环

    会了spfa这么长时间竟然不会判断负环,今天刚回.. [例题]poj3259 题目大意:当农场主 John 在开垦他的农场时,他发现了许多奇怪的昆虫洞.这些昆虫洞是单向的,并且可以把你从入口送到出口, ...

  10. spfa 判断负环 (转载)

    当然,对于Spfa判负环,实际上还有优化:就是把判断单个点的入队次数大于n改为:如果总的点入队次数大于所有点两倍 时有负环,或者单个点的入队次数大于sqrt(点数)有负环.这样时间复杂度就降了很多了. ...

随机推荐

  1. CART算法解密:从原理到Python实现

    本文深入探讨了CART(分类与回归树)算法的核心原理.实现方法以及应用场景.文章首先介绍了决策树的基础知识,然后详细解析了CART算法的工作机制,包括特征选择和树的构建.接着,通过Python和PyT ...

  2. 从源码分析 Redis 异步删除各个参数的具体作用

    以前对异步删除几个参数的作用比较模糊,包括网上的很多资料都是一笔带过,语焉不详. 所以这次从源码(基于 Redis 7.0.5)的角度来深入分析下这几个参数的具体作用: lazyfree-lazy-u ...

  3. 匿名远程启动jenkins的job

    安装jenkins插件Build Authorization Token Root job配置中的构建触发器,勾选触发远程构建,输入要用的令牌,如soul 通过jenkins地址调用触发 非参数化jo ...

  4. Batrix企业能力库之物流交易域能力建设实践

    简介 Batrix企业能力库,是京东物流战略级项目-技术中台架构升级项目的基础底座.致力于建立企业级业务复用能力平台,依托能力复用业务框架Batrix,通过通用能力/扩展能力的定义及复用,灵活支持业务 ...

  5. springBoot——多环境开发

    不常用的application.properties版的 常用的:application.yml版 #多环境开发,设置启用环境 spring: profiles: active: test --- # ...

  6. HDFS存储原理

    冗余数据保存问题: 一个数据块默认被保存三次 好处:1.加快数据传输错误(假如要同时访问数据块1 因为他冗余存储就会有3份 所以会加快数据传输速度) 2.很容易检查数据错误 3.保证数据可靠性 数据的 ...

  7. 解决swagger2 --> Illegal DefaultValue null for parameter type integer 保存问题

    在pmo.xml中加入两个依赖 <!--增加两个配置--> <dependency> <groupId>io.swagger</groupId> < ...

  8. 华企盾防泄密软件关于U盘无法注册问题

    1.以管理员权限运行控制台注册 2.如果是非加密注册可在USB拔插日志中右键日志远程注册 3.检查USB的驱动程序注册表是否都有 4.换一台电脑安装控制台注册 5.检查是否有与驱动有关的程序卸载试试 ...

  9. Educational Codeforces Round 159 总结

    最失败的一集. C 开题顺序搞错,不小心先开了C,以为是A.还好C不难. 题意大概是在给定的数组最后添一个数(所有数两两不同),再自定义一个数 \(k\) ,数组中每个数可以加上若干个 \(k\) , ...

  10. linux内核initcall放置在各个section中函数执行流程

    前言 linux以及嵌入式一些代码,我们看到core_initcall.device_initcall等等需要链接器分配各个section,并且在启动该模块时候执行.下面我们详细追溯一下执行过程. 作 ...