POJ3259---Wormholes(最短路:验证存在负环)
2017-06-26 19:43
344 查看
题目来源:http://poj.org/problem?id=3259
【题意】
农夫有n块地,这n块地有m条路径,具有相应的时间(走这条路),同时也有w个时间 虫洞,可以从一块地到另一块地,并且减少相应的时间,问:是否能够遇到之前的自己。。。
【思路】
m条路径是双向的,而w个虫洞是单向的。而这道题也就变成了判断是否存在负数环,因为一旦有了负数环,时间会不停地减少,肯定会遇见曾经的自己的。
验证是否存在负环的方法有两种:
1、用bellman_ford算法。经验证:所有的边重复松弛n-1次就可以得到最短路。那么如果松弛n-1次后依旧可以松弛,那么可证存在负环。(验证:bellman-ford算法的基本思想是,对图中除了源顶点s外的任意顶点u,依次构造从s到u的最短路径长度序列dist[u],dis2[u]……dis(n-1)[u],其中n是图G的顶点数,dis1[u]是从s到u的只经过1条边的最短路径长度,dis2[u]是从s到u的最多经过G中2条边的最短路径长度……当图G中没有从源可达的负权图时,从s到u的最短路径上最多有n-1条边。因此,
dist(n-1)[u]就是从s到u的最短路径长度(推荐博客:算法复习 – 图论 最短路和最小生成树))
2、用spfa算法。经验证:当一个点重复进入队列n次以上,就存在负环。
【代码】
【题意】
农夫有n块地,这n块地有m条路径,具有相应的时间(走这条路),同时也有w个时间 虫洞,可以从一块地到另一块地,并且减少相应的时间,问:是否能够遇到之前的自己。。。
【思路】
m条路径是双向的,而w个虫洞是单向的。而这道题也就变成了判断是否存在负数环,因为一旦有了负数环,时间会不停地减少,肯定会遇见曾经的自己的。
验证是否存在负环的方法有两种:
1、用bellman_ford算法。经验证:所有的边重复松弛n-1次就可以得到最短路。那么如果松弛n-1次后依旧可以松弛,那么可证存在负环。(验证:bellman-ford算法的基本思想是,对图中除了源顶点s外的任意顶点u,依次构造从s到u的最短路径长度序列dist[u],dis2[u]……dis(n-1)[u],其中n是图G的顶点数,dis1[u]是从s到u的只经过1条边的最短路径长度,dis2[u]是从s到u的最多经过G中2条边的最短路径长度……当图G中没有从源可达的负权图时,从s到u的最短路径上最多有n-1条边。因此,
dist(n-1)[u]就是从s到u的最短路径长度(推荐博客:算法复习 – 图论 最短路和最小生成树))
2、用spfa算法。经验证:当一个点重复进入队列n次以上,就存在负环。
【代码】
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int INF=0x3f3f3f3f; int n,m,w,k; struct p { int u,v; int t; }edge[5210]; int d[510]; bool bellman() { for(int i=2;i<=n;i++) { d[i]=INF; } d[1]=0; for(int i=1;i<n;i++)//重复n-1次 { bool flag=1;//是否存在负环 for(int j=0;j<k;j++)//所有的边 { if(d[edge[j].u]>d[edge[j].v]+edge[j].t) { d[edge[j].u]=d[edge[j].v]+edge[j].t; flag=0; } } if(flag) return 0;//若是当前这一轮没有松弛,那么一定不存在负环。 } for(int i=0;i<k;i++) { if(d[edge[i].u]>d[edge[i].v]+edge[i].t) return 1; } return 0; } int main() { int T; scanf("%d",&T); while(T--) { k=0; scanf("%d%d%d",&n,&m,&w); for(int i=1;i<=m;i++)//双向 { int u,v,t; scanf("%d%d%d",&u,&v,&t); edge[k].u=u; edge[k].v=v; edge[k++].t=t; edge[k].v=u; edge[k].u=v; edge[k++].t=t; } for(int i=1;i<=w;i++)//单向 { int u,v,t; scanf("%d%d%d",&u,&v,&t); edge[k].u=u; edge[k].v=v; edge[k++].t=-t;//时间减少 } if(bellman()) printf("YES\n"); else printf("NO\n"); } }
相关文章推荐
- POJ3259 Wormholes(最短路,有无负环,spfa,模板)
- Wormholes---poj3259(最短路 spfa 判断负环 模板)
- POJ3259 - Wormholes - 最短路判负环
- poj3259 Wormholes 最短路 spfa 负权环判断
- POJ3259 Wormholes 找负环
- poj 3259 Wormholes 图论 最短路 判负环
- POJ3259 Wormholes 洛谷P3385 【模板】负环
- poj3259 Wormholes 最短路bellman
- POJ-3259 Wormholes【单源最短路判负环】
- POJ 3259 Wormholes(floyd求负环,最短路)
- poj 3259 Wormholes 【spfa判断是否存在负环】
- poj3259 Wormholes【最短路-bellman-负环】
- POJ - 3259 Wormholes(SPFA最短路判断负环)
- [poj3259]Wormholes(spfa判负环)
- poj3259 Wormholes(最短路)
- POJ:3259-Wormholes(最短路判断负环)
- POJ3259----Wormholes(最短路)
- [模板]poj3259(判断是否存在负环)
- 【最短路】poj3259-Wormholes(Bellman-Ford 最短路)
- POJ-3259 Wormholes(最短路,bellman求负环)