最短路明显不会是次短路,因为题目说了次短一定是存在的,那么他们不可能重合,这样次短路肯定是最短路中某一条边不走,而走了其他边再回到最短路上,而且不可能绕两个地方,只可能绕一个地方,因为明显绕两个地方比绕一个地方的路径长,明显不是次短路了,所以我们枚举每条边;下面的代码用的是vector存图。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
#define sf scanf
#define pf printf
#define INF 1<<29
using namespace std;
const int N=5005;
int n,dis_s[N],dis_e[N];
bool vis[N];
typedef struct edge
{
int u,w;
}Edge;
vector<Edge> G[N];
void unit()
{
for(int i=1;i<=N-5;i++)
G[i].clear();
for(int i=1;i<=N-5;i++)
dis_s[i]=dis_e[i]=INF;
}
void spfa(int st,int d[])
{
int i,uu,vv;
queue<int> q;
memset(vis,0,sizeof(vis));
d[st]=0,vis[st]=1;
q.push(st);
while(!q.empty())
{
vv=q.front(),q.pop();
vis[vv]=0;
for(i=0;i<G[vv].size();i++)
{
uu=G[vv][i].u;
if(d[uu]>d[vv]+G[vv][i].w)
{
d[uu]=d[vv]+G[vv][i].w;
if(!vis[uu]) vis[uu]=1,q.push(uu);
}
}
}
}
int main()
{
int T,i,j,m,a,b,c,ca=0;
Edge tmp;
sf("%d",&T);
while(T--)
{
sf("%d%d",&n,&m);
unit();
while(m--)
{
sf("%d%d%d",&a,&b,&c);
tmp.u=b,tmp.w=c;
G[a].push_back(tmp);
tmp.u=a;
G[b].push_back(tmp);
}
spfa(1,dis_s);
spfa(n,dis_e);
int tmp1,ans=INF;
for(i=1;i<=n;i++)
{
for(j=0;j<G[i].size();j++)
{
b=G[i][j].u , c=G[i][j].w;
tmp1=dis_s[i]+dis_e[b]+c;
if(tmp1>dis_s[n]&&ans>tmp1) ans=tmp1;
}
}
pf("Case %d: %d\n",++ca,ans);
}
return 0;
}