HDU 6115 Factory LCA,暴力

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6115


题意:中文题面


分析:直接维护LCA,然后暴力枚举集合维护答案即可。

 

#include <bits/stdc++.h>
using namespace std;
const int maxn = 200010;
const int inf = 0x3f3f3f3f;
struct edge{
    int to,len,next;
}E[maxn*2];
vector<int>G[maxn];
int head[maxn],edgecnt,fa[maxn][20],dis[maxn],dep[maxn];
void init(){
    edgecnt=0;
    memset(head,-1,sizeof(head));
}
void add(int u, int v, int w){
    E[edgecnt].to=v,E[edgecnt].len=w,E[edgecnt].next=head[u],head[u]=edgecnt++;
}
void dfs(int x,int d,int Len, int pre){
    dis[x]=Len;
    dep[x] = d;
    fa[x][0]=pre;
    for(int i=1; i<20; i++){
        fa[x][i]=fa[fa[x][i-1]][i-1];
    }
    for(int i=head[x];~i;i=E[i].next){
        int v=E[i].to;
        if(v == pre) continue;
        int len=E[i].len;
        if(v==pre) continue;
        dfs(v, d+1, Len + len, x);
    }
}
int LCA(int u, int v){
    if(dep[u]<dep[v]) swap(u,v);
    for(int i=19; i>=0; i--){
        if(dep[fa[u][i]]>=dep[v]){
            u=fa[u][i];
        }
    }
    if(u==v) return u;
    for(int i=19; i>=0; i--){
        if(fa[u][i]!=fa[v][i]){
            u=fa[u][i];
            v=fa[v][i];
        }
    }
    return fa[u][0];
}
int n, m;
int getLen(int u, int v){
    int _lca = LCA(u,v);
    return dis[u]+dis[v]-2*dis[_lca];
}
int main()
{
    int T;
    scanf("%d", &T);
    while(T--)
    {
        for(int i=0; i<maxn; i++) G[i].clear();
        memset(dis, 0, sizeof(dis));
        memset(fa, 0, sizeof(fa));
        scanf("%d%d",&n,&m);
        init();
        for(int i=1; i<n; i++){
            int u,v,w;
            scanf("%d%d%d",&u,&v,&w);
            add(u,v,w);
            add(v,u,w);
        }
        dfs(1,0,0,-1);
        for(int i=1; i<=m; i++){
            int num,x;
            scanf("%d", &num);
            while(num--){
                scanf("%d",&x);
                G[i].push_back(x);
            }
        }
        int q;
        scanf("%d", &q);
        while(q--)
        {
            int a,b;
            scanf("%d%d",&a,&b);
            int ans = 0x3f3f3f3f;
            for(int i=0; i<G[a].size(); i++){
                for(int j=0; j<G[b].size(); j++){
                    ans = min(ans, getLen(G[a][i], G[b][j]));
                }
            }
            printf("%d\n", ans);
        }
    }
    return 0;
}

 

posted @ 2017-08-16 20:51  zxycoder  阅读(286)  评论(0编辑  收藏  举报