次短路的裸题,由于不是树不能用dp,所以spfa分情况讨论就好了
disa[x]+val[i]小于disa[v]时,将原来的disa[v]更新disb,然后disa[x]更新disa[v]
disa[x]+val[i]大于disa[v]时,如果disb[v]小于disb[x]+val[i]就可以用disa[x]+val[i]更新disb[v]
最后就是disa[v]==disa[x]+val[i]时,直接用disb[x]更新disb[v]就可以了。
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
#define inf 0x3c3c3c3c
using namespace std;
const int N=3e5+5;
int head[N],go[N],next[N],val[N];
int q[N],disa[N],disb[N];
bool vis[N];
int n,m,tot;
inline void spfa()
{
memset(vis,0,sizeof(vis));
fo(i,1,n)disa[i]=disb[i]=inf;
int t=0,w=1;
disa[1]=0;
vis[1]=1;
q[1]=1;
while (t!=w)
{
++t;
if (t==100001)t=0;
int x=q[t];
for(int i=head[x];i;i=next[i])
{
int v=go[i];
bool flag=0;
if (disa[x]+val[i]<disa[v])
{
disb[v]=min(disa[v],disb[x]+val[i]);
disa[v]=disa[x]+val[i];
flag=1;
}
else if (disa[x]+val[i]>disa[v]&&disa[x]+val[i]<disb[v])
{
disb[v]=disa[x]+val[i];
flag=1;
}
else if (disa[x]+val[i]==disa[v]&&disb[x]+val[i]<disb[v])
{
disb[v]=disb[x]+val[i];
flag=1;
}
if (flag&&!vis[v])
{
vis[v]=1;
++w;
if (w==100001)w=0;
q[w]=v;
}
}
vis[x]=0;
}
}
inline void add(int x,int y,int z)
{
go[++tot]=y;
next[tot]=head[x];
val[tot]=z;
head[x]=tot;
}
int main()
{
scanf("%d%d",&n,&m);
fo(i,1,m)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
add(x,y,z);
add(y,x,z);
}
spfa();
printf("%d\n",disb[n]);
return 0;
}