hdu3986枚举+最短路(删掉任意一条边的最长最短路)
本题和hdu1595是一个意思。可以看看
http://www.cnblogs.com/BruceNoOne/p/3252895.html
#include<iostream> #include<queue> using namespace std; const int N=1009; const int inf=1<<30; struct Node { int v,w,next; }e[N*N]; struct FA { int farther; int w; }fa[N];//用于存取唯一路径 int head[N],dis[N],vis[N]; int tot,n,m; void add(int a,int b,int w) { e[tot].v=b; e[tot].w=w; e[tot].next=head[a]; head[a]=tot++; } void spfa(int flag) { queue<int>q; int i; for(i=0;i<=n;i++) dis[i]=inf; memset(vis,0,sizeof(vis)); dis[1]=0; vis[1]=1; q.push(1); while(!q.empty()) { int u=q.front(); q.pop(); for(i=head[u];i+1;i=e[i].next) { int v=e[i].v; int w=dis[u]+e[i].w; if(dis[v]>w) { dis[v]=w; if(flag)//最短路的唯一路径,如果有重边,不保存权值,就会不知道是那条边, { fa[v].farther=u; fa[v].w=e[i].w; } if(!vis[v]) { vis[v]=1; q.push(v); } } } vis[u]=0; } } int main() { int t,a,b,w,i; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); memset(head,-1,sizeof(head)); tot=0; for(i=0;i<m;i++) { scanf("%d%d%d",&a,&b,&w); add(a,b,w); add(b,a,w); } fa[1].farther=-1; spfa(1); int u=n; int max=-1; while(fa[u].farther>0) { for(i=head[u];i+1;i=e[i].next) { if(e[i].v==fa[u].farther&&fa[u].w==e[i].w)//可以唯一确定一条边 { w=e[i].w; e[i].w=inf; a=i; break; } } for(i=head[fa[u].farther];i+1;i=e[i].next) { if(e[i].v==u&&w==e[i].w) { b=i; e[i].w=inf; break; } } spfa(0); u=fa[u].farther; e[a].w=e[b].w=w; if(dis[n]>max) max=dis[n]; if(max==inf) break; } if(max<inf) printf("%d\n",max); else printf("-1\n"); } return 0; }