#P1885. *【最短路】次短路[USACO06NOV] Roadblocks G
*【最短路】次短路[USACO06NOV] Roadblocks G
Description
【题意】给定 $N$ 个点 、$M$ 条无向边的无向图,求点 $1$ 至点 $N$ 的次短路长度。注:边可以重复走。
【输入格式】
第一行两个整数 $N、M$($1 \le N \le 5000 ,1 \le M \le 10^5$)。
下来 $M$ 行,每行包含三个整数 $x、y$ 、 $c$,表示一条连接 点$x$ 和点 $y$ 长度为 $c(1\le c \le 5000)$ 无向边。
【输出格式】
输出仅一个整数,表示次短路的长度。
【输入样例】
4 4
1 2 100
2 4 200
2 3 250
3 4 100
【输出样例】
450
【样例解释】
最短路:$1\rightarrow 2 \rightarrow 4$(长度为 100+200=300)
次短路:$1 \rightarrow 2 \rightarrow 3 \rightarrow 4$(长度为 100+250+100=450)
Hint
#include<bits/stdc++.h>
using namespace std;
const int N=5100,M=2e5+10;
struct edge{int x,y,c,pre;}a[M];int alen,last[N];
void ins(int x,int y,int c){alen++;a[alen]={x,y,c,last[x]};last[x]=alen;}
int read()
{
int x=0,f=1;char ch=getchar();
for(;!isdigit(ch);ch=getchar()){if(ch=='-')f=-1;}
for(;isdigit(ch);ch=getchar()) x=x*10+ch-48;
return x*f;
}
int n,m,d1[N],d2[N],v[N];
void spfa()
{
queue<int> q;q.push(1);
memset(d1,0x0f,sizeof(d1));d1[1]=0;
memset(d2,0x0f,sizeof(d2));
memset(v,0,sizeof(v));v[1]=1;
while(!q.empty())
{
int x=q.front();q.pop();v[x]=0;
for(int k=last[x];k;k=a[k].pre)
{
int y=a[k].y,c=a[k].c;
if(d1[y]>d1[x]+c)
{
d2[y]=d1[y];
d1[y]=d1[x]+c;
if(v[y]==0)q.push(y),v[y]=1;
}
if(d2[y]>d1[x]+c && d1[y]<d1[x]+c )
{
d2[y]=d1[x]+c;
if(v[y]==0)q.push(y),v[y]=1;
}
if(d2[y]>d2[x]+c )
{
d2[y]=d2[x]+c;
if(v[y]==0)q.push(y),v[y]=1;
}
}
}
}
int main()
{
n=read();m=read();
alen=0;memset(last,0,sizeof(last));
for(int i=1,x,y,c;i<=m;i++)
{
x=read();y=read();c=read();
ins(x,y,c);ins(y,x,c);
}
spfa();
printf("%d\n",d2[n]);
return 0;
}
</p>
相关
在下列比赛中: