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 */
浙公网安备 33010602011771号