题意
输入N和R代表N个路口,R条双向道路,
R(1≤R≤100,000),N(1≤N≤5000)
每一行包含三个以空格分隔的整数:A、B和D,描述一条连接A和B路口且长度为D(1≤D≤5000)的道路,求从1~N的次短路
思路
分别求出求出来从路口1和路口N道其他所有路口的最最短路距离并记录,然后遍历没条边,找到除了最短路之外从1~N最短的路径长。
#include<stdio.h>
#include<string.h>
#include<queue>
#include<algorithm>
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
#define N 100010
#define M 5010
ll dis1[M],dis2[M];
int n,m,k=0;
int head[M];
bool vis[M];
struct node
{
int u,v,w,next;
}edge[N*2];
void add(int u,int v,int w)
{
edge[k].u=u;
edge[k].v=v;
edge[k].w=w;
edge[k].next=head[u];
head[u]=k++;
}
void spfa(int s,ll *dis)
{
queue<int> q;
memset(vis,0,sizeof(vis));
fill(dis,dis+n+1,1e9);
q.push(s);
vis[s]=true;
dis[s]=0;
while(!q.empty())
{
int Q=q.front();
q.pop();
vis[Q]=false;
for(int i=head[Q];i!=-1;i=edge[i].next)
{
int to=edge[i].v;
if(dis[to]>dis[Q]+edge[i].w)
{
dis[to]=dis[Q]+edge[i].w;
if(!vis[to])
{
q.push(to);
vis[to]=true;
}
}
}
}
}
int main()
{
ll l,ans=inf;
while(~scanf("%d%d",&n,&m))
{
k=0;
memset(head,-1,sizeof(head));
memset(edge,0,sizeof(edge));
for(int i=0;i<m;i++){
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
add(a,b,c);
add(b,a,c);
}
spfa(1,dis1);
spfa(n,dis2);
l=dis1[n];
ll ans=inf;
for(int i=0;i<k;i++){
int u = edge[i].u, v = edge[i].v, w = edge[i].w;
if(dis1[u] + dis2[v] + w > l)
ans=min(ans , dis1[u] + dis2[v] + w); //从1到U+从N到v+u~v路径,按这种形式确定遍历所有边取最小
}
printf("%d\n",ans);
}
return 0;
}