POJ 3255 Roadblocks (次短路 SPFA )
Description
Bessie has moved to a small farm and sometimes enjoys returning to visit one of her best friends. She does not want to get to her old home too quickly, because she likes the scenery along the way. She has decided to take the second-shortest rather than the shortest path. She knows there must be some second-shortest path.
The countryside consists of R (1 ≤ R ≤ 100,000) bidirectional roads, each linking two of the N (1 ≤ N ≤ 5000) intersections, conveniently numbered 1..N. Bessie starts at intersection 1, and her friend (the destination) is at intersection N.
The second-shortest path may share roads with any of the shortest paths, and it may backtrack i.e., use the same road or intersection more than once. The second-shortest path is the shortest path whose length is longer than the shortest path(s) (i.e., if two or more shortest paths exist, the second-shortest path is the one whose length is longer than those but no longer than any other path).
Input
Line 1: Two space-separated integers: N and R
Lines 2..R+1: Each line contains three space-separated integers: A, B, and D that describe a road that connects intersections A and B and has length D (1 ≤ D ≤ 5000)
Output
Line 1: The length of the second shortest path between node 1 and node N
Sample Input
4 4
1 2 100
2 4 200
2 3 250
3 4 100
Sample Output
450
Hint
Two routes: 1 -> 2 -> 4 (length 100+200=300) and 1 -> 2 -> 3 -> 4 (length 100+250+100=450)
分析:
次短路不可能与最短路完全重合,那么就一定会有一段比较绕路。绕路的地方不可能超过两处,那样就有一条路短于这条路而长于最短路,矛盾。 因此可以对所有的边加以枚举。
首先用Dijkstra或SPFA以原点和终点为源分别做一次单源最短路,并把答案存在dist_0和dist_n两个数组中。那么,对于任何一条边(i, j),
下面的二者之一就有可能是次短路的长:
dist_0[i] + len(i, j) + dist_n[j] 和 dist_0[j] + len(i, j) + dist_n[i]
注意,如果其中一个的长度等于最短路的长度(即dist_n[0]),就一定不能选,因为这违反次短路的定义。两个都要枚举,因为可能有其中一个等于最短路的长,如果只取较小的值另外一个就废掉了。
#include<stdio.h>
#include<iostream>
#include<queue>
#include<string.h>
const int INF=0x3f3f3f3f;
using namespace std;
int n,m,cnt;
struct Node
{
int to,val;
int next;
} node[200100];
int head[5009],vis[5009];//寻找头结点,在找最短路的时候这个点有没有访问过
int dis_1[5009],dis_n[5009];//到1号节点的最短路,到n号节点的最短路
void add(int a,int b,int w)//将边的信息采用头插法保存下来
{
node[cnt].to=b;
node[cnt].val=w;
node[cnt].next=head[a];
head[a]=cnt;
cnt++;
}
void spfa(int st,int dis[])//spfa求最短路的模板
{
memset(vis,0,sizeof(vis));
queue<int>q;
dis[st]=0;
vis[st]=1;
q.push(st);
while(!q.empty())
{
int x=q.front();
q.pop();
vis[x]=0;
for(int i=head[x];i!=-1;i=node[i].next)
{
int y=node[i].to;
if(dis[y]>dis[x]+node[i].val)
{
dis[y]=dis[x]+node[i].val;
if(vis[y]==0)
{
vis[y]=1;
q.push(y);
}
}
}
}
}
int main()
{
int a,b,w;
while(~scanf("%d%d",&n,&m))
{
for(int i=0;i<=n;i++)//初始化
{
head[i]=-1;
dis_1[i]=dis_n[i]=INF;
}
cnt=0;//代表边数
for(int i=0; i<m; i++)
{
scanf("%d%d%d",&a,&b,&w);
add(a,b,w);
add(b,a,w);
}
spfa(1,dis_1);
spfa(n,dis_n);
int ans=INF;
//一条边一条边的通过绕路寻找次短路
for(int i=1;i<=n;i++)
{
for(int j=head[i];j!=-1;j=node[j].next)
{
b=node[j].to;
w=node[j].val;
int temp=dis_1[i]+w+dis_n[b];
if(temp>dis_1[n]&&ans>temp)
{
ans=temp;
}
}
}
printf("%d\n",ans);
}
return 0;
}
POJ 3255 Roadblocks (次短路 SPFA )的更多相关文章
- POJ 3255 Roadblocks (次级短路问题)
解决方案有许多美丽的地方.让我们跳回到到达终点跳回(例如有两点)....无论如何,这不是最短路,但它并不重要.算法能给出正确的结果 思考:而最短的路到同一点例程.spfa先正达恳求一次,求的最短路径的 ...
- poj 3255 Roadblocks 次短路(两次dijksta)
Roadblocks Time Limit : 4000/2000ms (Java/Other) Memory Limit : 131072/65536K (Java/Other) Total S ...
- POJ 3255 Roadblocks (次短路)
题意:给定一个图,求一条1-n的次短路. 析:次短路就是最短路再长一点呗,我们可以和求最短路一样,再多维护一个数组,来记录次短路. 代码如下: #pragma comment(linker, &quo ...
- POJ 3255 Roadblocks(A*求次短路)
Roadblocks Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 12167 Accepted: 4300 Descr ...
- POJ 3255 Roadblocks (次短路模板)
Roadblocks http://poj.org/problem?id=3255 Time Limit: 2000MS Memory Limit: 65536K Descriptio ...
- poj - 3225 Roadblocks(次短路)
http://poj.org/problem?id=3255 bessie 有时会去拜访她的朋友,但是她不想走最快回家的那条路,而是想走一条比最短的路长的次短路. 城镇由R条双向路组成,有N个路口.标 ...
- 次最短路径 POJ 3255 Roadblocks
http://poj.org/problem?id=3255 这道题还是有点难度 要对最短路径的算法非常的了解 明晰 那么做适当的修改 就可以 关键之处 次短的路径: 设u 到 v的边权重为cost ...
- poj 3255 Roadblocks
Roadblocks Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 13216 Accepted: 4660 Descripti ...
- POJ 3255 Roadblocks --次短路径
由于次短路一定存在,则可知次短路一定是最短路中某一条边不走,然后回到最短路,而且只是一条边,两条边以上不走的话,就一定不会是次短路了(即以边换边才能使最小).所以可以枚举每一条边,算出从起点到这条边起 ...
随机推荐
- 弱智python小游戏猜数字
from random import randintnum = randint(0,100)print("Guess what I think:?")bingo = Falsewh ...
- yaf windows安装
1.需要先下载 php_yaf模块.地址(http://pecl.php.net/package/yaf/2.3.2/windows) 看清你的php版本,然后在phpinfo中看Achitectur ...
- Redis&PHP的使用安装-windows版
Redis是一个Key-value的数据结构存储系统,可以以数据库的形式,缓存系统,消息处理器使用,它支持的存储value类型很多,例如,string.list(链表).set(集合).zset(so ...
- LInux查看网速带宽及各进程占用情况:nethogs
安装: #Ubuntu: sudo apt-get install nethogs #CentOS: sudo yum install nethogs 使用: $ sudo nethogs
- ajax发送post请求遇到的坑
前端小白的我. 用django-rest-framework写好了一个接口.如下,就接收两个字符串参数. 前端写了一个简单的提交post请求到这个接口,如下 浏览器提交请求后,一直提示 400 Bad ...
- MT【135】条件线性化
已知\(x,y>0,\dfrac{1}{x}+\dfrac{2}{y}=1\),求\(\dfrac{1}{x+1}+\dfrac{2}{y+1}\)的最大值_____ 解答:令\(a=\dfra ...
- Java中的三目运算符可能出现的问题
你真的了解Java中的三目运算符吗? 原创 2018-04-27 刨根问底的 Hollis Hollis Hollis 微信号 hollischuang 功能介绍 一个对Coding有着独特追求的人. ...
- git<commit和分支>
commit: 在执行提交命令git commit之前,一定要git add要修改的文件,这样才能将更改的内容更新到本地. 在Git 中提交时,会保存一个提交(commit)对象,它包含一个指向暂存内 ...
- (二)C语言文本流和二进制流的区别
转至:http://www.cnblogs.com/xiangzi888/archive/2011/11/10/2244336.html 一.首先回答,什么是文件,流 一个文件通常就是磁盘上的一段命名 ...
- poj 2774 后缀数组 两个字符串的最长公共子串
Long Long Message Time Limit: 4000MS Memory Limit: 131072K Total Submissions: 31904 Accepted: 12 ...