HDU ACM 3986 Harry Potter and the Final Battle(邻接表实现最短路dijkstra堆优化记录路径 + 枚举最短路上每条边)
http://acm.hdu.edu.cn/showproblem.php?pid=3986
题意:
从起点1 到 终点n,删除图中任意一条边求最短路的最坏情况。
n --表示有n个点
m --边数
f t l --f和t之间有一条长度为l的道路
<<<<<<<<<<<<本题有重边>>>>>>>>>>>>>>>>>
思路:
先做一次最短路,记录最短路的路径。
删边时枚举最短路上的每条边求删边后的最坏情况。
1 #include <iostream> 2 #include <queue> 3 #include <vector> 4 using namespace std; 5 const int maxm = 50000 + 10; 6 const int maxn = 1000 + 10; 7 const int INF = 0x3fffffff; 8 struct Node{ 9 int x; 10 int len; 11 const bool operator < (const Node a)const{ 12 return len > a.len; 13 } 14 }; 15 struct Edges{ 16 int from; 17 int to; 18 int len; 19 }; 20 vector <Edges> e; 21 vector <int> G[maxn];//每条边在e中的索引 22 int path[maxm]; 23 int n,m; 24 void Init(){ 25 int i; 26 for(i=0;i<=n;i++){//注意要清空所有。。。 27 G[i].clear(); 28 } 29 e.clear(); 30 memset(path,-1,sizeof(path)); 31 } 32 int dijkstra_find(int s){ 33 priority_queue <Node> q; 34 int used[maxn] = {0}; 35 int dir[maxn]; 36 int i; 37 for(i=0;i<=n;i++){ 38 dir[i] = INF; 39 } 40 dir[s] = 0; 41 Node a; 42 a.x = s; 43 a.len = 0; 44 q.push(a); 45 while(!q.empty()){ 46 int mid; 47 a = q.top(); 48 mid = a.x; 49 q.pop(); 50 if(!used[mid]){ 51 used[mid] = 1; 52 for(i=0;i<G[mid].size();i++){ 53 Edges &x = e[G[mid][i]]; 54 if(dir[x.to] > dir[mid] + x.len){ 55 dir[x.to] = dir[mid] + x.len; 56 path[x.to] = G[mid][i];//记录路径实际是索引,每次查找时都找到索引对应的边 57 a.x = x.to; 58 a.len = dir[x.to]; 59 q.push(a); 60 } 61 } 62 } 63 } 64 return dir[n]; 65 } 66 int dijkstra(int s,int index){ 67 priority_queue <Node> q; 68 int used[maxn] = {0}; 69 int dir[maxn]; 70 int i; 71 for(i=0;i<=n;i++){ 72 dir[i] = INF; 73 } 74 dir[s] = 0; 75 Node a; 76 a.x = s; 77 a.len = 0; 78 q.push(a); 79 while(!q.empty()){ 80 int mid; 81 a = q.top(); 82 mid = a.x; 83 q.pop(); 84 if(!used[mid]){ 85 used[mid] = 1; 86 for(i=0;i<G[mid].size();i++){ 87 if(G[mid][i] == index || G[mid][i] == (index^1)){//删去最短路的边与他的反边 88 continue; 89 } 90 Edges &x = e[G[mid][i]]; 91 if(dir[x.to] > dir[mid] + x.len){ 92 dir[x.to] = dir[mid] + x.len; 93 a.x = x.to; 94 a.len = dir[x.to]; 95 q.push(a); 96 } 97 } 98 } 99 } 100 return dir[n]; 101 } 102 void AddEdges(int from,int to,int len){ 103 Edges x; 104 x.from = from; 105 x.to = to; 106 x.len = len; 107 e.push_back(x); 108 int m = e.size(); 109 G[from].push_back(m-1); 110 } 111 int main(){ 112 int T; 113 scanf("%d",&T); 114 while(T--){ 115 Init(); 116 scanf("%d%d",&n,&m); 117 int i; 118 for(i=0;i<m;i++){ 119 int f,t,l; 120 scanf("%d%d%d",&f,&t,&l); 121 AddEdges(f,t,l); 122 AddEdges(t,f,l); 123 } 124 int ans = -INF; 125 ans = max(ans,dijkstra_find(1)); 126 int temp = n; 127 while(path[temp] != -1 && temp != 1){//path[temp] != -1过滤掉原来就不能到达的情况 temp != 1表示到达起点时结束 128 ans = max(ans,dijkstra(1,path[temp]));//因为求最坏情况,所以ans的值是INF时也要进行对比 129 temp = e[path[temp]].from; 130 } 131 if(ans == INF){ 132 cout<<-1<<endl; 133 } 134 else{ 135 printf("%d\n",ans); 136 } 137 } 138 return 0; 139 } 140 /* 141 Sample Input 142 1000 143 4 144 4 145 1 2 5 146 2 4 10 147 1 3 3 148 3 4 8 149 3 150 2 151 1 2 5 152 2 3 10 153 2 154 2 155 1 2 1 156 1 2 2 157 158 Sample Output 159 15 160 -1 161 2 162 163 */