zoukankan      html  css  js  c++  java
  • ACM-ICPC 2018 徐州赛区网络预赛 J. Maze Designer 最大生成树+lca

    题目链接: J. Maze Designer

    题解:把边界看成边然后,要求任意两点是只有一条最短路,很明显是颗树。然后求一颗最大生成树,加个lca,求两点距离就好了

    #include<bits/stdc++.h>
    #include <iostream>
    #include <string.h>
    #include <algorithm>
    #include <stdio.h>
    #include <math.h>
    #define ll long long
    #define pb push_back
    using namespace std;
    const int N=3e5+7;
    struct edge
    {
        int u,v,l;
        bool operator<(const edge b)const
        {
            return l>b.l;
        }
    };
    multiset<edge>st;
    int f[N],dep[N],fa[N][20],n,m;
    void init()
    {
        for(int i=0;i<N;i++)f[i]=i;
    }
    vector<int>g[N];
    int find(int x)
    {
        return x==f[x]?x:f[x]=find(f[x]);
    }
    void dfs(int v,int f,int d)
    {
        dep[v]=d;
        fa[v][0]=f;
        for(int to:g[v])
        {
            if(to!=f)
            {
                dfs(to,v,d+1);
            }
        }
    }
    int lca(int x,int y)
    {
        if(dep[x]<dep[y])swap(x,y);
        int k=dep[x]-dep[y];
        for(int i=19;i>=0;i--)
        {
            if(k>>i&1)
            {
                x=fa[x][i];
            }
        }
        if(x==y)return x;
        for(int i=19;i>=0;i--)
        {
            if(fa[x][i]!=fa[y][i])
            {
                x=fa[x][i];y=fa[y][i];
            }
        }
        return fa[x][0];
    }
    int main()
    {
        init();
        scanf("%d %d",&n,&m);
        char op[5];
        int le;
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=m;j++)
            {
               scanf("%s %d",op,&le);
               edge tmp;
               if(op[0]=='D')
               {
                    tmp.u=(i-1)*m+j;
                    tmp.v=tmp.u+m;
                    tmp.l=le;
                    st.insert(tmp);
               }
                scanf("%s %d",op,&le);
               if(op[0]=='R')
               {
                   tmp.u=(i-1)*m+j;
                    tmp.v=tmp.u+1;
                    tmp.l=le;
                    st.insert(tmp);
               }
            }
        }
        int cnt=n*m-1;
        while(cnt)
        {
            edge e=*st.begin();
            st.erase(st.begin());
            int fu=find(e.u),fv=find(e.v);
            if(fu!=fv)
            {
              //  cout<<e.l<<endl;
                f[fu]=fv;
                cnt--;
                g[e.u].pb(e.v);
                g[e.v].pb(e.u);
            }
        }
        dfs(1,0,0);
        for(int i=1;i<20;i++)
        {
            for(int j=1;j<=n*m;j++)
            {
                fa[j][i]=fa[fa[j][i-1]][i-1];
            }
        }
        int q,x,y,_x,_y;
        scanf("%d",&q);
        while(q--)
        {
            scanf("%d %d %d %d",&x,&y,&_x,&_y);
            int p1=(x-1)*m+y,p2=(_x-1)*m+_y;
            int ff=lca(p1,p2);
            printf("%d
    ",dep[p1]+dep[p2]-2*dep[ff]);
        }
        return 0;
    }
  • 相关阅读:
    python3中Requests将verify设置为False后,取消警告的方式
    unicode编码转换中文_python
    base64编解码_python
    数据结构学习之二叉树
    springboot全能框架学习之旅
    数据结构之树
    经典的猴子分香蕉问题
    求n个数的排列
    三元运算的应用
    将正整数分解成质因数乘积
  • 原文地址:https://www.cnblogs.com/lhclqslove/p/9619475.html
Copyright © 2011-2022 走看看