hdu1594枚举+最短路(删掉任意一条边的最长最短路)
本题的意思是删除任意一条边的情况下都满足的最短路。
分析:删除的边一定是最短上的边,才会使得最坏情况下的路径最短。所以需要删除最短路的边后枚举其他边的最短路。这题和hdu3986差不多,这题中边没有重边,而hdu3986有重边。保存路径是要注意。
我用的是spfa。也可以用dij+优先队列。
#include<iostream> #include<queue> using namespace std; const int N=1009; const int inf=1<<30; struct node { int v,w,next; }edge[N*N]; int head[N],vis[N],dis[N],fa[N]; int map[N][N]; int tot,n; void add(int a,int b,int w) { edge[tot].v=b; edge[tot].w=w; edge[tot].next=head[a]; head[a]=tot++; } void spfa(int flag) { queue<int> q; int i; memset(vis,0,sizeof(vis)); if(flag)memset(fa,-1,sizeof(fa)); for(i=0;i<=n;i++) { dis[i]=inf; } q.push(1); vis[1]=1; dis[1]=0; while(!q.empty()) { int u=q.front(); q.pop(); for(i=head[u];i+1;i=edge[i].next) { int v=edge[i].v; if(dis[v]>dis[u]+edge[i].w) { dis[v]=dis[u]+edge[i].w; if(flag)fa[v]=u; if(!vis[v]) { vis[v]=1; q.push(v); } } } vis[u]=0; } } int main() { int a,b,i,m,w; while(scanf("%d%d",&n,&m)!=EOF) { 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); } spfa(1); int u=n; int max=-1; while(fa[u]>0) { for(i=head[u];i+1;i=edge[i].next) { if(edge[i].v==fa[u]) { w=edge[i].w; edge[i].w=inf; a=i; break; } } for(i=head[fa[u]];i+1;i=edge[i].next) { if(u==edge[i].v) { edge[i].w=inf; b=i; break; } } spfa(0); edge[a].w=edge[b].w=w; u=fa[u]; if(dis[n]>max) max=dis[n]; } printf("%d\n",max); } return 0; }