题意:给出一张图,删去其中任意一条边,使得从1到n的最短路径最长
思路很简单,只要先求出1到n的最短路,然后枚举删去最短路上的边再求一次最短路,取其中最长的就行了
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
const int INF=10000000;
const int maxn=1111;
const int maxm=maxn*maxn;
int n,m;
struct node{
int to,w;
int next;
}e[maxm];
int head[maxn],dis[maxn],vis[maxn],pre[maxn],pos[maxn];
int edge;
void init()
{
memset(head,-1,sizeof(head));
memset(pre,-1,sizeof(pre));
memset(pos,-1,sizeof(pos));
edge=0;
}
void add(int u,int v,int w)
{
e[edge].to=v;
e[edge].w=w;
e[edge].next=head[u];
head[u]=edge++;
}
int dijkstra(int s)
{
int i,j,k,mn;
memset(vis,0,sizeof(vis));
for(int i=1; i<=n; i++) dis[i]=INF;
dis[1]=0;
for(i=0;i<n;++i)
{
k=s;
mn=INF;
for(j=1;j<=n;++j)
if(!vis[j]&&dis[j]<mn)
k=j,mn=dis[j];
vis[k]=1;
for(int i=head[k],v;~i; i=e[i].next)
{
v=e[i].to;
if(!vis[v]&&dis[k]+e[i].w<dis[v])
{
dis[v]=dis[k]+e[i].w;
//cout<<v<<" "<<i<<" "<<k<<endl;
pre[v]=i;
pos[v]=k;
}
}
}
return dis[n];
}
int dij(int x)
{
int s=1;
int i,j,k,mn;
memset(vis,0,sizeof(vis));
for(int i=1; i<=n; i++) dis[i]=INF;
dis[1]=0;
for(i=0;i<n-1; ++i)
{
k=s;
mn=INF;
for(j=1;j<=n;++j)
if(!vis[j]&&dis[j]<mn)
k=j,mn=dis[j];
vis[k]=1;
for(int i=head[k],v;~i; i=e[i].next)
{
//cout<<i<<endl;
v=e[i].to;
if(!vis[v]&&dis[k]+e[i].w<dis[v]&&i!=x)
{
//cout<<i<<" "<<e[i].w<<endl;
dis[v]=dis[k]+e[i].w;
}
}
}
return dis[n];
}
int main()
{
int t;
int u,v,w;
cin>>t;
while(t--)
{
init();
cin>>n>>m;
while(m--)
{
scanf("%d%d%d",&u,&v,&w);
add(u,v,w);
add(v,u,w);
}
//cout<<edge<<endl;
int ans=dijkstra(1);
//cout<<ans<<endl;
if(ans==INF)
cout<<"-1\n";
else
{
int flag=0;
for(int i=n;i!=1;i=pos[i])
{
//cout<<i<<endl;
ans=max(ans,dij(pre[i]));
if(ans==INF)
{
cout<<"-1\n";
flag=1;
break;
}
}
if(!flag)
cout<<ans<<endl;
}
}
return 0;
}