http://acm.hdu.edu.cn/showproblem.php?pid=1595
这道题我用spfa在枚举删除边的时候求最短路超时,改用dijkstra就过了。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <cstdio> 2 #include <queue> 3 #include <cstring> 4 #include <algorithm> 5 #define maxn 1001 6 using namespace std; 7 const int inf=1<<30; 8 9 int g[maxn][maxn]; 10 int n,m; 11 int s,e,c; 12 int dis[maxn]; 13 bool vis[maxn]; 14 int pre[maxn],pre1[maxn]; 15 16 /*void spfa() 17 { 18 queue<int>q; 19 memset(vis,false,sizeof(vis)); 20 for(int i=1; i<=n; i++) dis[i]=inf; 21 dis[1]=0; 22 vis[1]=true; 23 q.push(1); 24 pre[1]=-1; 25 while(!q.empty()) 26 { 27 int u=q.front(); q.pop(); 28 vis[u]=false; 29 for(int i=1; i<=n; i++) 30 { 31 if(dis[i]>dis[u]+g[u][i]&&g[u][i]!=inf) 32 { 33 dis[i]=dis[u]+g[u][i]; 34 pre[i]=u; 35 if(!vis[i]) 36 { 37 q.push(i); 38 vis[i]=true; 39 } 40 } 41 } 42 } 43 }*/ 44 45 void dijstra() 46 { 47 memset(vis,false,sizeof(vis)); 48 for(int i=1; i<=n; i++) dis[i]=(i==1?0:inf); 49 for(int i=1; i<=n; i++) 50 { 51 int x,mm=inf; 52 for(int y=1; y<=n; y++) if(!vis[y]&&dis[y]<mm) mm=dis[x=y]; 53 vis[x]=true; 54 for(int y=1; y<=n; y++) 55 { 56 if(dis[y]>dis[x]+g[x][y]&&!vis[y]) 57 { 58 pre[y]=x; 59 dis[y]=dis[x]+g[x][y]; 60 } 61 } 62 } 63 } 64 void solve() 65 { 66 int v1=n; 67 pre1[1]=-1; 68 while(pre[v1]!=-1) 69 { 70 pre1[v1]=pre[v1]; 71 v1=pre[v1]; 72 } 73 int v=n; 74 int max1=-1; 75 while(pre1[v]!=-1) 76 { 77 int mm=g[pre1[v]][v]; 78 g[pre1[v]][v]=g[v][pre1[v]]=inf; 79 dijstra(); 80 if(dis[n]!=inf) 81 max1=max(dis[n],max1); 82 g[pre1[v]][v]=g[v][pre1[v]]=mm; 83 v=pre1[v]; 84 } 85 printf("%d ",max1); 86 } 87 88 int main() 89 { 90 while(scanf("%d%d",&n,&m)!=EOF) 91 { 92 memset(pre,-1,sizeof(pre)); 93 for(int i=0; i<=n; i++) 94 { 95 for(int j=0; j<=n; j++) 96 { 97 if(i==j) g[i][j]=0; 98 else g[i][j]=inf; 99 } 100 } 101 for(int i=0; i<m; i++) 102 { 103 scanf("%d%d%d",&s,&e,&c); 104 g[s][e]=g[e][s]=min(g[s][e],c); 105 } 106 dijstra(); 107 solve(); 108 } 109 return 0; 110 }