5 6 1 2 4 1 3 3 2 3 1 2 4 4 2 5 7 4 5 1 6 7 1 2 1 2 3 4 3 4 4 4 6 4 1 5 5 2 5 2 5 6 5 5 7 1 2 8 1 4 10 2 3 9 2 4 10 2 5 1 3 4 7 3 5 10
11 13 27
题目意思刚开始一直没有看懂,后来查别人的才知道,其实就是找到最短路,逐次删掉其中一边,再分别求最短路长度,最后找到所有最短路中最长的。
一定要有保存原来节点的数组,因为每次调用dijkstra,pre都会改变,而删除的边要用到原来的节点,之前没有想清楚,调试了一个多小时才发现,还是自己水平不行啊!!!
#include <iostream> #include <memory.h> #include <stdio.h> #define NUM 1005 #define INF 0x3f3f3f3f using namespace std; int n; int g[NUM][NUM]; //保存修改之后的图 int dis[NUM][NUM]; //保存原图 int vis[NUM]; int lowcost[NUM]; int pre[NUM]; //用来保存每一次求最短路前驱节点 int path[NUM]; //用来保存最开始求的最短路前驱节点 void Dijkstra(int beg) { for(int i=1; i<=n; i++) { lowcost[i]=INF; vis[i]=false; pre[i]=-1; } lowcost[beg]=0; for(int j=1; j<=n; j++) { int k=-1; int Min=INF; for(int i=1; i<=n; i++) { if(!vis[i] && lowcost[i]<Min) { Min=lowcost[i]; k=i; } } if(k==-1)break; vis[k]=true; for(int i=1; i<=n; i++) { if(!vis[i] && lowcost[k]+g[k][i]<lowcost[i]) { lowcost[i]=lowcost[k]+g[k][i]; pre[i]=k; } } } } void printPath(int i) { if(i==1) return ; printPath(pre[i]); printf("%d->",i); } int main() { int m,a,b,v; while(cin>>n>>m) { for(int i=1; i<=n; i++) { for(int j=1; j<=n; j++) { g[i][j]=INF; } g[i][i]=0; } while(m--) { cin>>a>>b>>v; if(v<g[a][b]) { g[a][b]=g[b][a]=v; } } for(int i=1; i<=n; i++) { for(int j=1; j<=n; j++) { dis[i][j]=g[i][j]; } } int tmp=n; Dijkstra(1); for(int i=1;i<=n;i++) { path[i]=pre[i]; } //Dijkstra(1); int Max=-1; while(tmp!=1) { //printf("cut:%d-%d\n",tmp,path[tmp]); g[tmp][path[tmp]]=g[path[tmp]][tmp]=INF; //cout<<endl; Dijkstra(1); /*for(int i=1; i<=n; i++) 输出当前存储节点 { cout<<"pre["<<i<<"]:"<<pre[i]<<endl; }*/ //cout<<lowcost[n]<<endl; if(lowcost[n]>Max) { Max=lowcost[n]; } g[tmp][path[tmp]]=g[path[tmp]][tmp]=dis[tmp][path[tmp]]; tmp=path[tmp]; //cout<<"tmp:"<<tmp<<endl; } cout<<Max<<endl; } return 0; }