http://acm.hdu.edu.cn/showproblem.php?pid=3986
从开始的最短路里依次删一条边,求新的最短路,求最长的最短路
删边操作要标记节点以及节点对应的边
#include <iostream> #include <cstdio> #include <cstring> #include <queue> using namespace std ; const int INF=0xfffffff ; struct node{ int s,t,v,nxt ; }e[100005] ; int n,m,cnt,dis[1005],vis[1005],head[1005],fa[1005],pre[1005],flag,mk[1005] ; int add(int s,int t,int v) { e[cnt].s=s ; e[cnt].t=t ; e[cnt].v=v ; e[cnt].nxt=head[s] ; head[s]=cnt++ ; } void spfa() { for(int i=1 ;i<=n ;i++) dis[i]=INF ; memset(vis,0,sizeof(vis)) ; dis[1]=0 ; vis[1]=1 ; queue <int> q ; q.push(1) ; while(!q.empty()) { int u=q.front() ; q.pop() ; vis[u]=0 ; for(int i=head[u] ;i!=-1 ;i=e[i].nxt) { int tt=e[i].t ; if(!flag && mk[tt] && (pre[tt]==i || pre[tt]==i+1))continue ; if(dis[tt]>e[i].v+dis[u]) { dis[tt]=e[i].v+dis[u] ; if(flag) { fa[tt]=u ; pre[tt]=i ; } if(!vis[tt]) { vis[tt]=1 ; q.push(tt) ; } } } } } int main() { int t ; scanf("%d",&t) ; while(t--) { scanf("%d%d",&n,&m) ; cnt=1 ; memset(head,-1,sizeof(head)) ; memset(mk,0,sizeof(mk)) ; for(int i=0 ;i<m ;i++) { int s,t,v ; scanf("%d%d%d",&s,&t,&v) ; add(s,t,v) ;add(t,s,v) ; } flag=1 ; spfa() ; flag=0 ; int ans=0 ; for(int i=n ;i!=1 ;i=fa[i]) { mk[i]=1 ; spfa() ; if(dis[n]==INF) { ans=-1 ; break ; } ans=max(ans,dis[n]) ; mk[i]=0 ; } printf("%d\n",ans) ; } return 0 ; }