您的位置:首页 > 其它

bzoj1726【Usaco2006 Nov】Roadblocks第二短路

2015-10-19 23:53 381 查看

1726: [Usaco2006 Nov]Roadblocks第二短路

Time Limit: 5 Sec  Memory Limit: 64 MB
Submit: 907  Solved: 441

[Submit][Status][Discuss]

Description

贝茜把家搬到了一个小农场,但她常常回到FJ的农场去拜访她的朋友。贝茜很喜欢路边的风景,不想那么快地结束她的旅途,于是她每次回农场,都会选择第二短的路径,而不象我们所习惯的那样,选择最短路。 贝茜所在的乡村有R(1<=R<=100,000)条双向道路,每条路都联结了所有的N(1<=N<=5000)个农场中的某两个。贝茜居住在农场1,她的朋友们居住在农场N(即贝茜每次旅行的目的地)。
贝茜选择的第二短的路径中,可以包含任何一条在最短路中出现的道路,并且,一条路可以重复走多次。当然咯,第二短路的长度必须严格大于最短路(可能有多条)的长度,但它的长度必须不大于所有除最短路外的路径的长度。 

Input

* 第1行: 两个整数,N和R,用空格隔开 
* 第2..R+1行: 每行包含三个用空格隔开的整数A、B和D,表示存在一条长度为 D(1 <= D <= 5000)的路连接农场A和农场B

Output

* 第1行: 输出一个整数,即从农场1到农场N的第二短路的长度 

Sample Input

4 4

1 2 100

2 4 200

2 3 250

3 4 100

Sample Output

450

输出说明:

最短路:1 -> 2 -> 4 (长度为100+200=300)

第二短路:1 -> 2 -> 3 -> 4 (长度为100+250+100=450)

HINT

Source

Gold

以1和n分别为起点跑spfa,将每个点最短路径记作d[i][0]和d[i][1]。再枚举每一条边,用d[i][0]+d[e[j].to]+e[j].w更新答案。注意这里的次短路是严格大于最短路。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
#define F(i,j,n) for(int i=j;i<=n;i++)
#define D(i,j,n) for(int i=j;i>=n;i--)
#define LL long long
#define MAXN 200050
#define INF 1000000000
using namespace std;
struct edge_type
{
int next,to,w;
}e[MAXN];
int n,m,a,b,x,cnt=0,d[5005][2],ans=INF,head[5005],tmp;
bool inq[5005];
queue<int> q;
int read()
{
int x=0;
char ch=getchar();
while (ch<'0'||ch>'9') ch=getchar();
while (ch>='0'&&ch<='9')
{
x=x*10+ch-'0';
ch=getchar();
}
return x;
}
void add_edge(int u,int v,int w)
{
e[++cnt].to=v;
e[cnt].w=w;
e[cnt].next=head[u];
head[u]=cnt;
}
void spfa(int s,int p)
{
memset(inq,false,sizeof(inq));
d[s][p]=0;
q.push(s);
inq[s]=true;
while (!q.empty())
{
int y=q.front();
inq[y]=false;
q.pop();
for(int i=head[y];i;i=e[i].next) if (d[e[i].to][p]>d[y][p]+e[i].w)
{
d[e[i].to][p]=d[y][p]+e[i].w;
if (!inq[e[i].to])
{
q.push(e[i].to);
inq[e[i].to]=true;
}
}
}
}
int main()
{
memset(d,0x7f,sizeof(d));
memset(head,0,sizeof(head));
n=read(); m=read();
F(i,1,m)
{
a=read(); b=read(); x=read();
add_edge(a,b,x);
add_edge(b,a,x);
}
spfa(1,0);
spfa(n,1);
F(i,1,n) for(int j=head[i];j;j=e[j].next)
{
tmp=d[i][0]+d[e[j].to][1]+e[j].w;
if (tmp>d
[0]&&tmp<ans) ans=tmp;
}
printf("%d\n",ans);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: