HDU 3986 Harry Potter and the Final Battle Dijkstra + 堆优化

http://acm.hdu.edu.cn/showproblem.php?pid=3986

题意:

  起点为1,终点为N,伏地魔会将任意一条路径删除,要求算出删除任意一条边后的最短路径中最大的一个,

伏地魔的角度来说就是,想删一条路harry走到终点的距离尽可能大。

 

坑爹:

  有重边,有反向边。删边的时候要记得连反边一起删除。

 

解法:

  用了个dijkstra + 堆优化的模板,因为伏地魔要删除harry的最短路径上的边才起到干扰的效果,所以枚举删除

最短路径上的每一条边,每枚举一次计算出一次最短路,只要有计算不出的就输出-1,不然就输出最大的最短路。

 

  1 #include<iostream>
  2 #include<vector>
  3 #include<set>
  4 using namespace std;
  5 
  6 const int maxn = 100000 + 10;
  7 const int INF = 0x3fffffff;
  8 
  9 struct Edge {
 10     int from;
 11     int to;
 12     int values;
 13     int next;
 14 }edge[maxn];
 15 
 16 int t;
 17 int n;
 18 int m;
 19 int count_Edge;
 20 int dis[maxn];
 21 bool used[maxn];
 22 int pre[maxn];
 23 int path[maxn];
 24 bool used_Edge[maxn];
 25 int path_Edge[maxn];
 26 
 27 struct cmp {
 28     bool operator () (const int &a,const int &b) const
 29     {
 30         if(dis[a] == dis[b])
 31         {
 32             return a < b;
 33         }
 34         return dis[a] < dis[b];
 35     }
 36 };
 37 
 38 void initDis()
 39 {
 40     memset(used,0,sizeof(used));
 41     int i;
 42     for(i=0; i<maxn; i++)
 43     {
 44         dis[i] = INF;
 45     }
 46 }
 47 
 48 void init()
 49 {
 50     count_Edge = 0;
 51     memset(used_Edge,0,sizeof(used_Edge));
 52     memset(path,-1,sizeof(path));
 53     memset(path_Edge,-1,sizeof(path_Edge));
 54     memset(pre,-1,sizeof(pre));
 55     memset(edge,0,sizeof(edge));
 56     initDis();
 57 }
 58 
 59 void addEdge(int from, int to, int values)
 60 {
 61     edge[count_Edge].from = from;
 62     edge[count_Edge].to = to;
 63     edge[count_Edge].values = values;
 64     edge[count_Edge].next = pre[from];
 65     pre[from] = count_Edge++;
 66 
 67     edge[count_Edge].from = to;
 68     edge[count_Edge].to = from;
 69     edge[count_Edge].values = values;
 70     edge[count_Edge].next = pre[to];
 71     pre[to] = count_Edge++;
 72 }
 73 
 74 int dijkstra(int begin,int end,int flag)
 75 {
 76     set<int,cmp> S;
 77     S.clear();
 78     dis[begin] = 0;
 79     path[begin] = begin;
 80     S.insert(begin);
 81     while(!S.empty())
 82     {
 83         int st = *S.begin();
 84         if(st == end)
 85         {
 86             return dis[end];
 87         }
 88         S.erase(st);
 89         used[st] = true;
 90         int i;
 91         for(i = pre[st]; i != -1; i = edge[i].next)
 92         {
 93             Edge e = edge[i];
 94             if(!used[e.to] && dis[e.to] > dis[st] + e.values && !used_Edge[i])
 95             {
 96                 S.erase(e.to);
 97                 path[e.to] = st;
 98                 if(!flag)
 99                 {
100                     path_Edge[e.to] = i;
101                 }
102                 dis[e.to] = dis[st] + e.values;
103                 S.insert(e.to);
104             }
105         }
106     }
107     return -1;
108 }
109 
110 int main()
111 {
112     cin>>t;
113     while(t--)
114     {
115         init();
116         cin>>n>>m;
117         int i;
118         for(i=0; i<m; i++)
119         {
120             int from;
121             int to;
122             int values;
123             cin>>from>>to>>values;
124             addEdge(from, to, values);
125         }
126         int ans = dijkstra(1,n,0);
127         if(ans == -1 || ans == INF)
128         {
129             cout<<-1<<endl;
130             continue;
131         }
132         int cut[maxn];
133         int k = 0;
134         int x = n;
135         int max =  -1;
136         while(path_Edge[x] != -1)
137         {
138             initDis();
139             used_Edge[path_Edge[x]] = true;
140             used_Edge[path_Edge[x]^1] = true;
141             ans = dijkstra(1,n,1);
142             if(ans == -1 || dis[n] == INF)
143             {
144                 max = -1;
145                 break;
146             }
147             if(max < ans)
148             {
149                 max = ans;
150             }
151             used_Edge[path_Edge[x]] = false;
152             used_Edge[path_Edge[x]^1] = false;
153             x = edge[path_Edge[x]].from;
154         }
155         cout<<max<<endl;
156     }
157     return 0;
158 }
159 
160 /*
161 1
162 2 2
163 1 2 1
164 1 2 1
165 
166 10
167 3 4
168 1 2 10
169 2 1 11
170 3 2 10
171 3 2 11
172 
173 10
174 2 3
175 1 2 1
176 1 2 2
177 1 2 3
178 */
View Code

 

posted @ 2013-08-24 16:20  pc....  阅读(358)  评论(0)    收藏  举报