您的位置:首页 > 其它

【bzoj 3732】Network

2016-08-26 23:09 225 查看
注意:此题为货车运输的变式,要先更新最值,在更新节点,不然用更新以后的节点再更新最值就不对了。

先求最小生成树,再倍增求lca。

#include <bits/stdc++.h>
using namespace std;
const int maxn = 30010;
const int Maxn = 15010;
struct edge{
int from, to, dis;
};
int _first[Maxn], _next[maxn], _to[maxn], _dis[maxn], cnt;
int fa[Maxn], deep[Maxn], _fa[Maxn];
int up[Maxn][25], max_dis[Maxn][25];
edge e[maxn];
bool cmp(edge a, edge b){
return a.dis < b.dis;
}
int find(int x){
if(_fa[x] == x) return x;
return _fa[x] = find(_fa[x]);
}
void add(int a, int b, int c){
_next[++cnt] = _first[a];
_first[a] = cnt;
_to[cnt] = b;
_dis[cnt] = c;
}
void dfs(int now, int dep){
deep[now] = dep;
up[now][0] = fa[now];
for(int i = 1; i <= 20; i ++){
up[now][i] = up[up[now][i-1]][i-1];
max_dis[now][i] = max(max_dis[now][i-1], max_dis[up[now][i-1]][i-1]);
}
for(int i = _first[now]; i; i = _next[i]){
if(_to[i] != fa[now]){
fa[_to[i]] = now;
max_dis[_to[i]][0] = _dis[i];
dfs(_to[i], dep+1);
}
}
}
int lca(int a, int b){
int max1 = 0, max2 = 0;
if(deep[a] != deep[b]){
if(deep[a] < deep[b]) swap(a,b);
while(deep[fa[a]] != deep[b]){
int i = 0;
while(deep[up[a][i]] > deep[b]) i ++;
i --;
max1 = max(max1, max_dis[a][i]);
a = up[a][i];
}
max1 = max(max1, max_dis[a][0]);
a = fa[a];
}
if(a == b) return max(max1, max2);
while(fa[a] != fa[b]){
int i = 0;
while(up[a][i] != up[b][i]) i ++;
i --;
max1 = max(max1, max_dis[a][i]);
max2 = max(max2, max_dis[b][i]);
a = up[a][i], b = up[b][i];
}
return max(max(max1, max_dis[a][0]), max(max2, max_dis[b][0]));
}
int main(){
int n, m, k;
scanf("%d%d%d", &n, &m, &k);
for(int i = 1; i <= n; i ++) _fa[i] = i;
memset(max_dis, 128, sizeof max_dis);
for(int i = 1; i <= m; i ++){
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
e[i] = (edge){a,b,c};
}
sort(e+1, e+1+m, cmp);
for(int i = 1, num = 0;i<=m&& num < n; i ++){
if(find(e[i].from) != find(e[i].to)){
_fa[_fa[e[i].from]] = e[i].to;
add(e[i].from, e[i].to, e[i].dis);
add(e[i].to, e[i].from, e[i].dis);
num ++;
}
}
fa[1] = 1;
dfs(1,1);
for(int i = 1; i <= k; i ++){
int a, b;
scanf("%d%d", &a, &b);
printf("%d\n", lca(a,b));
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  倍增