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 */

 

posted @ 2013-04-16 21:09  zx雄  阅读(1143)  评论(0编辑  收藏  举报