• ACM-ICPC 2018 徐州赛区网络预赛 J. Maze Designer 最大生成树 lca


     大概就是要每两个点 只能有一条路径,并且约束,最短的边用来砌墙,那么反之的意思就是最大的边用来穿过

    故最大生成树

    生成以后 再用lca计算树上两点间的距离

    (当然防止生成树是一条链,可以用树的重心作为根) ,然后简单的统计下树上两点的距离就行了

    #include <bits/stdc++.h>
    using namespace std;
    
    const int N = 510*510*2;
    int n, m, sum, fa[N];
    
    struct node {
        int u,v,val;
        node(){}
        node(int uu,int vv,int va):u(uu),v(vv),val(va){}
    }E[N]; int etot;
    
    int Id(int x,int y) {
        return (x-1)*m+y;
    }
    
    int Find(int x) {
        return fa[x] == x ? x : fa[x]=Find(fa[x]);
    }
    
    bool join(int u,int v) {
        int fu = Find(u);
        int fv = Find(v);
        if(fu!=fv) {
            fa[fu] = fv;
            return true;
        }
        return false;
    }
    
    int tot, head[N], nex[N], son[N], dep[N], f[N][20];
    void add(int u,int v) {
        nex[++tot] = head[u];
        son[tot] = v;
        head[u] = tot;
    }
    
    void addEdge(int u,int v) {
        add(u,v);
        add(v,u);
    }
    
    void dfs(int x,int fa) {
        f[x][0] = fa;
        for(int i=1; f[x][i-1]; i++) {
            f[x][i] = f[f[x][i-1]][i-1];
        }
        for(int i=head[x]; i; i=nex[i]) {
            if(son[i] != fa) {
                dep[son[i]] = dep[x] + 1;
                dfs(son[i],x);
            }
        }
    }
    void Lca(int u,int v) {
        if(dep[u] < dep[v])
            swap(u,v);
        int ans = dep[u]-dep[v];
        for(int i=19;i>=0;i--) {
            if(dep[u] - (1<<i) >= dep[v])
                u=f[u][i];
        }
        for(int i=19;i>=0;i--) {
            if(f[u][i] != f[v][i])
                u=f[u][i], v=f[v][i], ans+=(1<<(i+1));
        }
        if(u!=v) ans+=2;
        printf("%d
    ",ans);
    }
    
    int main ()
    {
        freopen("in.txt","r",stdin);
        scanf("%d %d", &n, &m);
        sum=n*m;
        for(int i=1;i<=n;i++) {
            for(int j=1;j<=m;j++) {
                int x,y; scanf("%*s %d %*s %d", &x, &y);
                if(i < n)
                    E[++etot]=node(Id(i,j), Id(i+1,j), x);
                if(j < m)
                    E[++etot]=node(Id(i,j), Id(i,j+1), y);
            }
        }
        sort(E+1,E+1+etot,[](node a,node b) {
             return a.val > b.val;
        });
        for(int i=0;i<=sum;i++)
            fa[i] = i;
        for(int i=1; i<=etot; i++) {
            int u = E[i].u;
            int v = E[i].v;
            //if(join(u,v))
                //addEdge(u,v);
            int fu = Find(u), fv = Find(v);
            if(fu == fv) continue;
            fa[fu] = fa[fv];
            addEdge(u,v);
        }
        dfs(1,0);
        int Q; scanf("%d",&Q);
        while (Q--) {
            int x1,y1,x2,y2;
            scanf("%d %d %d %d",&x1,&y1,&x2,&y2);
            Lca(Id(x1,y1),Id(x2,y2));
        }
        return 0;
    }
  • 相关阅读:
    字符串型
    字符型
    实型(浮点型)
    sizeof
    数据类型
    标识符
    Win32汇编
    Win32汇编
    C# 语言程序设计笔记
    鬼泣4:寻找无限生命/剑气/暴怒
  • 原文地址:https://www.cnblogs.com/Draymonder/p/9619303.html
Copyright © 2020-2023  润新知