hdu 3986 Harry Potter and the Final Battle
Harry Potter and the Final Battle
Time Limit: 5000/3000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 3319 Accepted Submission(s):
936
Problem Description
The final battle is coming. Now Harry Potter is located
at city 1, and Voldemort is located at city n. To make the world peace as soon
as possible, Of course, Harry Potter will choose the shortest road between city
1 and city n. But unfortunately, Voldemort is so powerful that he can choose to
destroy any one of the existing roads as he wish, but he can only destroy one.
Now given the roads between cities, you are to give the shortest time that Harry
Potter can reach city n and begin the battle in the worst case.
Input
First line, case number t (t<=20).
Then for each case: an integer n (2<=n<=1000) means the number of city in the magical world, the cities are numbered from 1 to n. Then an integer m means the roads in the magical world, m (0< m <=50000). Following m lines, each line with three integer u, v, w (u != v,1 <=u, v<=n, 1<=w <1000), separated by a single space. It means there is a bidirectional road between u and v with the cost of time w. There may be multiple roads between two cities.
Then for each case: an integer n (2<=n<=1000) means the number of city in the magical world, the cities are numbered from 1 to n. Then an integer m means the roads in the magical world, m (0< m <=50000). Following m lines, each line with three integer u, v, w (u != v,1 <=u, v<=n, 1<=w <1000), separated by a single space. It means there is a bidirectional road between u and v with the cost of time w. There may be multiple roads between two cities.
Output
Each case per line: the shortest time to reach city n
in the worst case. If it is impossible to reach city n in the worst case, output
“-1”.
Sample Input
3
4
4
1 2 5
2 4 10
1 3 3
3 4 8
3
2
1 2 5
2 3 10
2
2
1 2 1
1 2 2
Sample Output
15
-1
2
Author
tender@WHU
Source
题意:一个无向图,n个点,m条边,输入m条边的起点,终点,距离,假设减去其中任意一条边,问各种情况下的最短路中最长的是哪条,可能有重边。
这题和1595非常像,但是因为可能有重边(删去一边边,还是可以走另一条路的情况),所以必须使用邻接表写。
附上代码:
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <queue> 5 #define N 1005 6 #define M 50005 7 #define INF 0x3f3f3f3f 8 using namespace std; 9 10 struct Edge 11 { 12 int from,to,val; 13 int next; 14 bool used; 15 } edge[M*2]; 16 17 int n,m,tol; 18 int head[M*2],dis[N]; 19 bool vis[N]; 20 int flag; 21 int path[N]; 22 23 void init() 24 { 25 tol=0; 26 flag=0; 27 memset(head,-1,sizeof(head)); 28 memset(path,-1,sizeof(path)); 29 } 30 31 void addEdge(int u,int v,int val) 32 { 33 edge[tol].from=u; 34 edge[tol].to=v; 35 edge[tol].val=val; 36 edge[tol].used=true; 37 edge[tol].next=head[u]; 38 head[u]=tol++; 39 edge[tol].from=v; 40 edge[tol].to=u; 41 edge[tol].val=val; 42 edge[tol].used=true; 43 edge[tol].next=head[v]; 44 head[v]=tol++; 45 } 46 47 void getmap() 48 { 49 scanf("%d%d",&n,&m); 50 int a,b,c; 51 while(m--) 52 { 53 scanf("%d%d%d",&a,&b,&c); 54 addEdge(a,b,c); 55 } 56 } 57 58 int spfa() 59 { 60 memset(dis,INF,sizeof(dis)); 61 memset(vis,false,sizeof(vis)); 62 queue<int>q; 63 q.push(1); 64 dis[1]=0; 65 vis[1]=true; 66 while(!q.empty()) 67 { 68 int u=q.front(); 69 q.pop(); 70 vis[u]=false; 71 for(int i=head[u]; i!=-1; i=edge[i].next) 72 { 73 int v=edge[i].to; 74 if(edge[i].used) 75 if(dis[v]>dis[u]+edge[i].val) 76 { 77 dis[v]=dis[u]+edge[i].val; 78 if(!flag) 79 path[v]=i; ///记录可以缩进的边,这些边可以改变总路程 80 if(!vis[v]) 81 { 82 vis[v]=true; 83 q.push(v); 84 } 85 } 86 } 87 } 88 return dis[n]; 89 } 90 91 void newmap() 92 { 93 int i=n,j=-1; 94 int ans=-1; 95 while(path[i]!=-1) 96 { 97 j=path[i]; 98 edge[j].used=edge[j+1].used=false; 99 int tmp=spfa(); 100 edge[j].used=edge[j+1].used=true; 101 if(tmp>ans) 102 ans=tmp; 103 i=edge[j].from; 104 } 105 if(ans<INF) 106 printf("%d\n",ans); 107 else 108 printf("-1\n"); 109 } 110 111 int main() 112 { 113 int T; 114 scanf("%d",&T); 115 while(T--) 116 { 117 init(); 118 getmap(); 119 spfa(); 120 newmap(); 121 } 122 }