您的位置:首页 > 其它

HDU6074 Phone Call(LCA+并查集)

2017-09-22 10:33 344 查看

HDU6074 Phone Call(LCA+并查集)

代码

#include <stdio.h>
#include <algorithm>
using namespace std;
typedef long long ll;
const int maxn = 100100;
const int M = 20;
struct Node{
int a, b, c, d, w;
bool operator < (const Node &r){
return w < r.w;
}
}o[maxn];
struct Edge{
int u, v, nxt;
}e[2 * maxn];
int f[maxn], sz[maxn], head[maxn], e_cnt, deep[maxn], pa[maxn][M + 2], g[maxn];
ll cost[maxn];
void Add(int u, int v){
int id = e_cnt++;
e[id].u = u;
e[id].v = v;
e[id].nxt = head[u];
head[u] = id;
}
void DFS(int u, int fa){
deep[u] = deep[fa] + 1;
pa[u][0] = fa;
for(int i = 1; i < M; i++)
pa[u][i] = pa[pa[u][i-1]][i-1];
for(int id = head[u]; id != -1; id = e[id].nxt)
if(e[id].v != fa) DFS(e[id].v, u);
}
int LCA(int u, int v){
if(deep[u] < deep[v]) swap(u, v);
int dif = deep[u] - deep[v];
for(int i = 0; i < M; i++)
if((dif >> i) & 1) u = pa[u][i];
for(int i = M - 1; i >= 0; i--)
if(pa[u][i] != pa[v][i]){
u = pa[u][i];
v = pa[v][i];
}
return u == v ? u : pa[u][0];
}
int Find(int *f, int u){ return f[u] == u ? u : f[u] = Find(f, f[u]); }
void Union(int u, int v, int c){
int fu = Find(f, u), fv = Find(f, v);
if(fu != fv){
sz[fu] += sz[fv];
cost[fu] += cost[fv] + c;
f[fv] = fu;
}
}
void Merge(int u, int v, int c){
for(int r = Find(g, u); deep[r] > deep[v]; r = Find(g, r)){
Union(r, pa[r][0], c);
g[r] = pa[r][0];
}
}
int main(){
int T; scanf("%d", &T);
while(T--){
int n, m;
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; i++)
head[i] = -1;
e_cnt = 0;
for(int i = 1; i < n; i++){
int u, v;
scanf("%d%d", &u, &v);

8e4a
Add(u, v);
Add(v, u);
}
for(int i = 1; i <= m; i++)
scanf("%d%d%d%d%d", &o[i].a, &o[i].b, &o[i].c, &o[i].d, &o[i].w);
sort(o + 1, o + 1 + m);
for(int i = 1; i <= n; i++){
f[i] = g[i] = i;
sz[i] = 1;
cost[i] = 0;
}
DFS(1, 0);
for(int i = 1; i <= m; i++){
int u = LCA(o[i].a, o[i].b), v = LCA(o[i].c, o[i].d);
Merge(o[i].a, u, o[i].w);
Merge(o[i].b, u, o[i].w);
Merge(o[i].c, v, o[i].w);
Merge(o[i].d, v, o[i].w);
Union(u, v, o[i].w);
/*
for(int j = 1; j <= n; j++)
printf("%d ", f[j]);
printf("\n");
for(int j = 1; j <= n; j++)
printf("%d ", g[j]);
printf("\n\n");
*/
}
printf("%d %lld\n", sz[Find(f, 1)], cost[Find(f, 1)]);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: