zoukankan      html  css  js  c++  java
  • EOJ-A 昔我往矣(倍增LCA+乱搞)

    题解:

    既然只有5个点,那就无限乱搞,我的做法是不断取出当前点集两两之间的LCA插入点集,直到所有两两之间的LCA都已经在点集中了。

    这一步的时间复杂度我感觉是一个调和级数,是可以被忽略的。

    然后对每个点保存它的最深父亲,然后对点集建一棵树,对这棵树算边权贡献即可。

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=2e5+100;
    int n,q;
    struct node {
        int u,v,w,nxt;
    }edge[maxn<<1];
    int head[maxn],tot;
    void addedge (int u,int v,int w) {
        edge[tot].u=u;
        edge[tot].v=v;
        edge[tot].w=w;
        edge[tot].nxt=head[u];
        head[u]=tot++;
        
        edge[tot].u=v;
        edge[tot].v=u;
        edge[tot].w=w;
        edge[tot].nxt=head[v];
        head[v]=tot++;
    } 
    
    int father[30][maxn];
    int h[maxn],d[maxn];
    void dfs (int x) {
        for (int i=head[x];i!=-1;i=edge[i].nxt) {
            int v=edge[i].v;
            if (v==father[0][x]) continue;
            father[0][v]=x;
            h[v]=h[x]+1;
            d[v]=d[x]+edge[i].w;
            //printf("%d %d
    ",v,h[v]);
            dfs(v);
        }
    }
    int lca (int x,int y) {
        if (h[x]<h[y]) swap(x,y);
        for (int i=20;i>=0;i--)
            if (h[x]-h[y]>>i) x=father[i][x];
        if (x==y) return x;
        for (int i=20;i>=0;i--) 
            if (father[i][x]!=father[i][y]) {
                x=father[i][x];
                y=father[i][y];
            }
        return father[0][x];
    }
    int getDis (int x,int y) {
        return d[x]+d[y]-d[lca(x,y)]*2;
    }
    int getH (int x,int y) {
        return h[x]+h[y]-h[lca(x,y)]*2;
    }
    int x[maxn],ans,f[maxn];
    vector<int> g[maxn];
    void dfs1 (int x,int f) {
        for (int y:g[x]) {
            if (y==f) continue;
            ans+=getDis(x,y);
            dfs1(y,x);
        }
    }
    int main () {
        scanf("%d",&n);
        for (int i=1;i<=n;i++) head[i]=-1;
        for (int i=1;i<n;i++) {
            int u,v,w;
            scanf("%d%d%d",&u,&v,&w);
            u++,v++;
            addedge(u,v,w);
        }
        h[1]=1;
        dfs(1);
        for (int i=1;i<=20;i++) for (int j=1;j<=n;j++) father[i][j]=father[i-1][father[i-1][j]];
        scanf("%d",&q);
        while (q--) {
            for (int i=1;i<=5;i++) scanf("%d",x+i),x[i]++;
            int m=5;
            set<int> st;
            for (int i=1;i<=5;i++) {
                st.insert(x[i]);
            }
            while (1) {
                int f=1;
                for (int i=1;i<=m;i++) {
                    for (int j=i+1;j<=m;j++) {
                        int tt=lca(x[i],x[j]);
                        if (!st.count(tt)) {
                            st.insert(tt);
                            x[++m]=tt;
                            f=0;
                        }
                    }
                }
                if (f) break;
            }
            for (int i=1;i<=m;i++) f[x[i]]=0,g[x[i]].clear(); 
            for (int i=1;i<=m;i++) {
                for (int j=i+1;j<=m;j++) {
                    int tt=lca(x[i],x[j]);
                    if (tt==x[i]) {
                        if (h[x[i]]>h[f[x[j]]]) {
                            f[x[j]]=x[i];
                        }
                    }
                    else if (tt==x[j]) {
                        if (h[x[j]]>h[f[x[i]]]) {
                            f[x[i]]=x[j];
                        }
                    }
                }
            }
            int rt=0;
            for (int i=1;i<=m;i++) {
                //printf("%d %d
    ",x[i],f[x[i]]);
                if (!f[x[i]]) {
                    rt=x[i];
                    continue;
                }
                g[f[x[i]]].push_back(x[i]);
            }
            ans=0;
            dfs1(rt,0);
            printf("%d
    ",ans);
        }
    }
  • 相关阅读:
    git this exceeds GitHub's file size limit of 100.00 MB
    使用vue-cli创建vue工程
    【转】Visual Studio Code必备插件
    linux安装openssl
    Centos7离线安装mysql8
    使用nmon来按频率采集数据
    Mac下编译android4.0.4遇到的问题
    32位ubuntu16.4编译android4.1.1
    vmvare安装vmtools菜单灰色
    Substrate 使用
  • 原文地址:https://www.cnblogs.com/zhanglichen/p/14382413.html
Copyright © 2011-2022 走看看