HDU6074 Phone Call(LCA+并查集)

来源:互联网 发布:英语图表数据作文模板 编辑:程序博客网 时间:2024/06/03 20:52

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);            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;}
原创粉丝点击