zoukankan      html  css  js  c++  java
  • 北方大学 ACM 多校训练赛 第七场 C Castle(LCA)

    【题意】给你N个点,N条不同的边,Q次询问,求出u,v之间的最短路。

    【分析】题意很简单,就是求最短路,但是Q次啊,暴力DIJ?当然不行,观察到这个题边的数目和点的数目是相同的,也就是说这个图是由一棵树加了一条边而形成的。而对于一棵树,如果有Q次询问最短路,那就可以用LCA来做,复杂度QlogN,但是现在加了一条边,可能会使有些点之间的路径变短。假设多加的这条边的两个端点是U,V,那么对于询问的X,Y,有这么三种情况,直接过LCA,或者经过U,V,详情见代码。

    #include <bits/stdc++.h>
    #define met(a,b) memset(a,b,sizeof a)
    #define pb push_back
    #define mp make_pair
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define lowbit(x) (x&(-x))
    using namespace std;
    typedef long long ll;
    ll mod = 1e9+7;
    const int N=3e4+50;
    const int M=N*N+10;
    int n,m,k,root,son,dis[N],dep[N],fa[N][20],parent[N];
    int d;
    vector<pair<int,int> >edg[N];
    int Find(int x){
        if(parent[x]!=x)parent[x]=Find(parent[x]);
        return parent[x];
    }
    void Union(int x,int y){
        x=Find(x);
        y=Find(y);
        if(x==y)return;
        parent[y]=x;
    }
    void dfs(int u,int f){
        fa[u][0]=f;
        for(int i=1; i<20; i++){
            fa[u][i]=fa[fa[u][i-1]][i-1];
        }
        for(int i=0; i<edg[u].size(); i++){
            int v=edg[u][i].first;
            if(v==f)continue;
            dis[v]=dis[u]+edg[u][i].second;
            dep[v]=dep[u]+1;
            dfs(v,u);
        }
    }
    int Lca(int u,int v){
        int U=u,V=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 main(){
        int u,v,w;
        int T;
        scanf("%d",&T);
        while(T--){
            for(int i=0; i<N; i++)dis[i]=dep[i]=0,edg[i].clear(),parent[i]=i;
            met(fa,-1);
            scanf("%d%d",&n,&m);
            for(int i=1; i<=n; i++){
                scanf("%d%d%d",&u,&v,&w);
                u++;v++;
                if(Find(u)==Find(v))root=u,son=v,d=w;
                else{
                    Union(u,v);
                    edg[u].pb(mp(v,w));
                    edg[v].pb(mp(u,w));
                }
            }
            dep[root]=1;
            dfs(root,-1);
            while(m--){
                scanf("%d%d",&u,&v);
                u++;v++;
                int lca=Lca(u,v);
                int ans1=dis[u]+dis[v]-2*dis[lca];
                int ans2=dis[u]+dis[son]-2*dis[Lca(u,son)]+dis[v]+dis[root]-2*dis[Lca(root,v)]+d;
                int ans3=dis[v]+dis[son]-2*dis[Lca(v,son)]+dis[u]+dis[root]-2*dis[Lca(root,u)]+d;
                printf("%d
    ",min(ans1,min(ans2,ans3)));
            }
        }
        return 0;
    }
  • 相关阅读:
    mybatis映射文件之获取自增的主键
    mybatis映射文件之基本的增删改查
    mybatis之全局配置文件中的标签
    org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.gong.mybatis.dao.EmployeeMapper.getEmpById
    mybatis之第一个mybatis程序(二)
    mybatis之第一个mybatis程序(一)
    mybatis之在eclipase中的mybatis配置文件中按下"alt+/"提示相应的标签
    springmvc之与spring进行整合
    使用 JAVA 中的动态代理实现数据库连接池
    ThreadLocal源代码分析
  • 原文地址:https://www.cnblogs.com/jianrenfang/p/6715146.html
Copyright © 2011-2022 走看看