hdu 6115 Factory LCA

来源:互联网 发布:mac 4k 字体太小 编辑:程序博客网 时间:2024/06/05 10:05

题目链接




 这个题目 O(qn2 logn)10s能跑过?逗我玩啊...暴力真的是靠勇气啊.

  数据不想吐槽了,百毒之星 . 直接预处理每个节点到根节点的距离,然后暴力枚举LCA 维护最小..


#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>#include<set>#include<vector>#include<queue>#include<map>#define inf 0x3f3f3f3f#define  pii  pair<int, int>  using namespace std;typedef long long ll;const ll mod=1e9+7;const int maxn=2e5+10;int depth[maxn],parent[maxn][30];int dis[maxn];//parent表示每次往上走2^k步的父亲,dis表示每次走2^k路径的最小值  vector<int>vt[maxn];vector<pii>G[maxn];int t,n,m,q;void clear(){    for(int i=1;i<maxn;i++)    G[i].clear();    for(int i=1;i<maxn;i++)    vt[i].clear();}void dfs(int u,int fa,int dep,int d){depth[u]=dep;dis[u]=d;for(int i=1;i<20;i++){parent[u][i]=parent[parent[u][i-1]][i-1];}int len=G[u].size();for(int i=0;i<len;i++){int v=G[u][i].first;if(v==fa)continue;parent[v][0]=u;dfs(v,u,dep+1,d+G[u][i].second);}}int lca(int u,int v){if(depth[u]<depth[v])swap(u,v);int k=depth[u]-depth[v];for(int i=0;i<20;i++){if((1<<i)&k)  u=parent[u][i];}if(u!=v){for(int i=19;i>=0;i--){if(parent[u][i]!=parent[v][i]){u=parent[u][i];v=parent[v][i];}}u=parent[u][0];}return u;}int get_dis(int u,int v){int f=lca(u,v);return dis[u]+dis[v]-2*dis[f];}int main(){    cin>>t;    while(t--)    {                scanf("%d %d",&n,&m);        clear();        int x,y,z;        for(int i=1;i<n;i++)        {            scanf("%d %d %d",&x,&y,&z);            G[x].push_back(make_pair(y,z));            G[y].push_back(make_pair(x,z));        }        for(int i=1;i<=m;i++)        {            scanf("%d",&x);            while(x--)            {                scanf("%d",&y);                vt[i].push_back(y);            }        }        dfs(1,-1,0,0);                scanf("%d",&q);        while(q--)        {int res=inf;            scanf("%d %d",&x,&y);            int len1=vt[x].size();            int len2=vt[y].size();            for(int i=0;i<len1;i++)            {                int v=vt[x][i];                for(int j=0;j<len2;j++)                { if(res==0)                break;                    int u=vt[y][j];                    if(u==v)                    {                        res=0;                        break;                    }                }                           }            for(int i=0;i<len1;i++)            {            int v=vt[x][i];            for(int j=0;j<len2;j++)            {            if(res==0) break;            int u=vt[y][j];            res=min(res,get_dis(u,v));}}            printf("%d\n",res);        }  }    return 0;}


原创粉丝点击