uva 11354 Bond
题意:
邦德在逃命!他在一个有N个城市,由M条边连接的道路网中。一条路的危险度被定义为这条路上危险度最大的边的危险度。
现在给出若干个询问,s,t,问从s到t的最小的危险度是多少。
思路:
首先可以证明这条路是固定的,就是最小生成树,证明略。
之后就是计算生成树上两点间的最长边,用prim算法预处理的话,由于N的规模较大,所以会超时。
由于MST是一棵树,想到树上两点之间的距离有O(log(n))的求法,即倍增求lca,按照同样的处理方法,只不过维护最大值,就可以在O(log(n))的时间内求出两点之间的最长边,查询为Q,总复杂度Qlog(n)。
代码:
1 #include <stdio.h> 2 #include <string.h> 3 #include <algorithm> 4 #include <vector> 5 #include <math.h> 6 using namespace std; 7 8 const int maxn = 50005; 9 //const int inf = 0x3f3f3f3f; 10 11 struct edge 12 { 13 int fr,to,len; 14 15 edge(int a,int b,int c) 16 { 17 fr = a; 18 to = b; 19 len = c; 20 } 21 }; 22 23 bool cmp(edge x,edge y) 24 { 25 return x.len < y.len; 26 } 27 28 vector<edge> g[maxn],es; 29 int p[maxn][35]; 30 int fa[maxn]; 31 int par[maxn]; 32 bool vis[maxn]; 33 int md[maxn][35]; 34 int deep[maxn]; 35 36 int fin(int x) 37 { 38 if (x == par[x]) return x; 39 else return par[x] = fin(par[x]); 40 } 41 42 void unit(int x,int y) 43 { 44 x = fin(x); 45 y = fin(y); 46 47 if (x == y) return; 48 49 par[x] = y; 50 } 51 52 void dfs(int u) 53 { 54 vis[u] = 1; 55 56 for (int i = 0;i < g[u].size();i++) 57 { 58 edge e = g[u][i]; 59 60 int to = e.to; 61 62 if (vis[to]) continue; 63 64 fa[to] = u; 65 66 deep[to] = deep[u] + 1; 67 68 md[to][0] = e.len; 69 70 dfs(to); 71 } 72 } 73 74 void pre_deal(int n) 75 { 76 for (int i = 0;i <= n;i++) 77 { 78 p[i][0] = fa[i]; 79 } 80 81 //int sz = (int)(log(n*1.0) / log(2.0)) + 1; 82 83 for (int j = 1;j<= 20;j++) 84 { 85 for (int i = 1;i <= n;i++) 86 { 87 p[i][j] = p[p[i][j-1]][j-1]; 88 md[i][j] = max(md[i][j-1],md[p[i][j-1]][j-1]); 89 } 90 } 91 } 92 93 int query(int a,int b,int n) 94 { 95 if (deep[a] < deep[b]) swap(a,b); 96 97 int c = deep[a] - deep[b]; 98 99 int ans = 0; 100 101 //int sz = (int)(log(n * 1.0) / log(2.0)) + 1; 102 103 for (int i = 0;i <= 20;i++) 104 { 105 if (c & (1 << i)) 106 { 107 ans = max(ans,md[a][i]); 108 a = p[a][i]; 109 //printf("%d **\n",ans); 110 } 111 } 112 113 if (a == b) return ans; 114 else 115 { 116 for (int i = 20;i >= 0;i--) 117 { 118 if (p[a][i] != p[b][i]) 119 { 120 ans = max(ans,md[a][i]); 121 ans = max(ans,md[b][i]); 122 123 a = p[a][i]; 124 b = p[b][i]; 125 } 126 } 127 } 128 129 ans = max(ans,md[a][0]); 130 ans = max(ans,md[b][0]); 131 132 return ans; 133 } 134 135 void init(int n) 136 { 137 for (int i = 0;i <= n;i++) 138 { 139 g[i].clear(); 140 par[i] = i; 141 } 142 143 es.clear(); 144 145 memset(vis,0,sizeof(vis)); 146 memset(md,0,sizeof(md)); 147 memset(deep,0,sizeof(deep)); 148 memset(md,0,sizeof(md)); 149 } 150 151 int main() 152 { 153 int n,m; 154 155 int kase = 0; 156 157 while (scanf("%d%d",&n,&m) != EOF) 158 { 159 if (kase++) printf("\n"); 160 161 init(n); 162 163 for (int i = 0;i < m;i++) 164 { 165 int a,b,c; 166 167 scanf("%d%d%d",&a,&b,&c); 168 169 es.push_back(edge(a,b,c)); 170 } 171 172 sort(es.begin(),es.end(),cmp); 173 174 for (int i = 0;i < m;i++) 175 { 176 int x = es[i].fr,y = es[i].to; 177 178 if (fin(x) == fin(y)) continue; 179 180 unit(x,y); 181 182 g[x].push_back(edge(x,y,es[i].len)); 183 g[y].push_back(edge(y,x,es[i].len)); 184 } 185 186 deep[1] = 0; 187 // 188 dfs(1); 189 //printf("233\n"); 190 pre_deal(n); 191 192 int q; 193 194 scanf("%d",&q); 195 196 for (int i = 0;i < q;i++) 197 { 198 int a,b; 199 200 int ans = 0; 201 202 scanf("%d%d",&a,&b); 203 204 ans = query(a,b,n); 205 206 printf("%d\n",ans); 207 } 208 } 209 210 return 0; 211 }
康复训练中~欢迎交流!