uva 11354 Bond

Posted Omz

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 }

 

以上是关于uva 11354 Bond的主要内容,如果未能解决你的问题,请参考以下文章

题解 UVA11354 Bond

UVA - 11354 Bond(最小生成树+LCA+瓶颈路)

训练指南 UVA - 11354(最小生成树 + 倍增LCA)

uva(11354) 最小瓶颈生成树+LCA

UVA 11354 LCA+最小生成树

Linux网卡bond