题目连接
题目大意:给一个n个点m条边的图,求在删掉一条边的情况下从1到n最短路的最大值。
分析:同hdu1595,但与它不同的是这个题是由重边的,所以要注意对重边的处理,这里用链式前向星存图,假设删掉的边为num,那么num^1就是其反向边,每次枚举这两条边不可使用就好了。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<queue>
#include<stack>
#include<vector>
#include<map>
#include<cstring>
#define PII pair<int,int>
#define x first
#define y second
#define lk (k<<1)
#define rk (k<<1|1)
using namespace std;
typedef long long ll;
const double eps=1e-8;
const double pi=acos(-1.0);
const int inf=0x3f3f3f3f;
const int N=1e3+10,M=5e4+10;
inline int read()
{
int res=0,sign=1;
char c;
c=getchar();
while(c<'0'||c>'9')
{
if(c=='-') sign=-1;
c=getchar();
}
while(c>='0'&&c<='9')
{
res=res*10+c-'0';
c=getchar();
}
return sign*res;
}
struct edge
{
int u,v,next,w;
}e[M<<1];
int head[N],cnt;
void add(int u,int v,int w)
{
e[cnt].v=v;
e[cnt].u=u;
e[cnt].w=w;
e[cnt].next=head[u];
head[u]=cnt++;
}
int n,m;
int vis[N],dis[N],pre[N],path[N],len;
void dijkstra(int s,int num)
{
priority_queue<PII>q;
for(int i=1;i<=n;i++) vis[i]=0,dis[i]=inf;
dis[s]=0;
q.push(make_pair(-dis[s],s));
while(!q.empty())
{
int u=q.top().y;
q.pop();
if(vis[u]) continue;
vis[u]=1;
for(int i=head[u];i!=-1;i=e[i].next)
{
int v=e[i].v;
if(num!=-1&&(i==num||i==(num^1))) continue;
if(dis[v]>dis[u]+e[i].w){
dis[v]=dis[u]+e[i].w;
if(num==-1) pre[v]=i;
q.push(make_pair(-dis[v],v));
}
}
}
}
void get_path(int p,int q)
{
int now=q;
while(now!=p)
{
path[++len]=pre[now];
now=e[pre[now]].u;
}
}
int main()
{
int t;
t=read();
while(t--)
{
n=read();
m=read();
cnt=len=0;
memset(head,-1,sizeof(head));
for(int i=1;i<=m;i++){
int u,v,w;
u=read();
v=read();
w=read();
add(u,v,w);
add(v,u,w);
}
dijkstra(1,-1);
if(dis[n]==inf){
printf("-1\n");
continue;
}
get_path(1,n);
int ans=0;
for(int i=1;i<=len;i++){
dijkstra(1,path[i]);
ans=max(ans,dis[n]);
}
printf("%d\n",ans==inf?-1:ans);
}
return 0;
}