题意:求次短路,且次短路需严格大于最短路长度。
【分析】
从起点和终点分别跑一遍spfa,枚举每条边判断。
【代码】
//bzoj 1726 第二短路
#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define M(a) memset(a,0,sizeof a)
#define fo(i,j,k) for(i=j;i<=k;i++)
using namespace std;
const int mxn=100005;
queue <int> q;
struct edge {int to,w,next;} f[mxn<<1];
bool vis[mxn];
int head[mxn],dis[mxn][2];
int n,m,cnt,ans=1e9,mn;
inline void add(int u,int v,int w)
{
f[++cnt].to=v,f[cnt].w=w,f[cnt].next=head[u],head[u]=cnt;
f[++cnt].to=u,f[cnt].w=w,f[cnt].next=head[v],head[v]=cnt;
}
inline void spfa(int s,int t,int k)
{
int i,j,u,v,w;
M(vis);
dis[s][k]=0;
q.push(s);
while(!q.empty())
{
u=q.front();
q.pop();
vis[u]=0;
for(i=head[u];i;i=f[i].next)
{
v=f[i].to,w=f[i].w;
if(dis[v][k]>dis[u][k]+w)
{
dis[v][k]=dis[u][k]+w;
if(!vis[v]) q.push(v),vis[v]=1;
}
}
}
mn=dis[t][k];
}
int main()
{
freopen("block.in","r",stdin);
freopen("block.out","w",stdout);
int i,j,u,v,w;
scanf("%d%d",&n,&m);
while(m--)
{
scanf("%d%d%d",&u,&v,&w);
add(u,v,w);
}
memset(dis,0x3f,sizeof dis);
spfa(1,n,0),spfa(n,1,1); //第1次从起点跑,第二次从终点跑
fo(u,1,n)
for(i=head[u];i;i=f[i].next)
{
v=f[i].to,w=f[i].w;
if(dis[u][0]+dis[v][1]+w>mn)
ans=min(ans,dis[u][0]+dis[v][1]+w);
}
printf("%d\n",ans);
return 0;
}