zoukankan      html  css  js  c++  java
  • poj 1986 Distance Queries 带权lca 模版题

    Distance Queries
     

    Description

    Farmer John's cows refused to run in his marathon since he chose a path much too long for their leisurely lifestyle. He therefore wants to find a path of a more reasonable length. The input to this problem consists of the same input as in "Navigation Nightmare",followed by a line containing a single integer K, followed by K "distance queries". Each distance query is a line of input containing two integers, giving the numbers of two farms between which FJ is interested in computing distance (measured in the length of the roads along the path between the two farms). Please answer FJ's distance queries as quickly as possible! 

    Input

    * Lines 1..1+M: Same format as "Navigation Nightmare" 

    * Line 2+M: A single integer, K. 1 <= K <= 10,000 

    * Lines 3+M..2+M+K: Each line corresponds to a distance query and contains the indices of two farms. 

    Output

    * Lines 1..K: For each distance query, output on a single line an integer giving the appropriate distance. 

    Sample Input

    7 6
    1 6 13 E
    6 3 9 E
    3 5 7 S
    4 1 3 N
    2 4 20 W
    4 7 2 S
    3
    1 6
    1 4
    2 6
    

    Sample Output

    13
    3
    36
    

    Hint

    Farms 2 and 6 are 20+3+13=36 apart. 
    模版题
    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<string>
    #include<queue>
    #include<algorithm>
    #include<stack>
    #include<cstring>
    #include<vector>
    #include<list>
    #include<set>
    #include<map>
    #define true ture
    #define false flase
    using namespace std;
    #define ll long long
    #define inf 0xfffffff
    int scan()
    {
        int res = 0 , ch ;
        while( !( ( ch = getchar() ) >= '0' && ch <= '9' ) )
        {
            if( ch == EOF )  return 1 << 30 ;
        }
        res = ch - '0' ;
        while( ( ch = getchar() ) >= '0' && ch <= '9' )
            res = res * 10 + ( ch - '0' ) ;
        return res ;
    }
    #define maxn 100010
    #define M 22
    struct is
    {
        int v,next,w;
    } edge[maxn*2];
    int deep[maxn],jiedge;
    int dis[maxn];
    int head[maxn];
    int rudu[maxn];
    int fa[maxn][M];
    void add(int u,int v,int w)
    {
        jiedge++;
        edge[jiedge].v=v;
        edge[jiedge].w=w;
        edge[jiedge].next=head[u];
        head[u]=jiedge;
    }
    void dfs(int u)
    {
        for(int i=head[u]; i; i=edge[i].next)
        {
            int v=edge[i].v;
            int w=edge[i].w;
            if(!deep[v])
            {
                dis[v]=dis[u]+edge[i].w;
                deep[v]=deep[u]+1;
                fa[v][0]=u;
                dfs(v);
            }
        }
    }
    void st(int n)
    {
        for(int j=1; j<M; j++)
            for(int i=1; i<=n; i++)
                fa[i][j]=fa[fa[i][j-1]][j-1];
    }
    int LCA(int u , int v)
    {
        if(deep[u] < deep[v]) swap(u , v) ;
        int d = deep[u] - deep[v] ;
        int i ;
        for(i = 0 ; i < M ; i ++)
        {
            if( (1 << i) & d )  // 注意此处,动手模拟一下,就会明白的
            {
                u = fa[u][i] ;
            }
        }
        if(u == v) return u ;
        for(i = M - 1 ; i >= 0 ; i --)
        {
            if(fa[u][i] != fa[v][i])
            {
                u = fa[u][i] ;
                v = fa[v][i] ;
            }
        }
        u = fa[u][0] ;
        return u ;
    }
    void init()
    {
        memset(head,0,sizeof(head));
        memset(fa,0,sizeof(fa));
        memset(rudu,0,sizeof(rudu));
        memset(deep,0,sizeof(deep));
        jiedge=0;
    }
    int main()
    {
        int x,n,t;
        while(~scanf("%d%d",&n,&x))
        {
            init();
    
            for(int i=0; i<x; i++)
            {
                char a[2];
                int u,v,w;
                scanf("%d%d%d %s",&u,&v,&w,a);
                add(u,v,w);
                add(v,u,w);//双向可以从任意点开始,并且避免有环
            }
                    deep[1]=1;
                    dis[1]=0;
                    dfs(1);
            st(n);
            scanf("%d",&t);
            while(t--)
            {
                int a,b;
                scanf("%d%d",&a,&b);
                printf("%d
    ",dis[a]-2*dis[LCA(a,b)]+dis[b]);
            }
        }
        return 0;
    }
  • 相关阅读:
    Java进阶——带你入门分布式中的Nginx
    详细介绍Spring Boot 2.0的那些新特性与增强
    Kafka对Java程序员有多重要?连阿里都再用它处理亿万级数据统计
    C#面向对象的三大特性
    汽车租赁系统 封装。继承和多态
    深入C#数据类型小部分第二章
    Java面向对象的三大特征
    SQL Server 存储过程
    一篇文章教你学会基础的HTML
    初步了解Entity Framework
  • 原文地址:https://www.cnblogs.com/jhz033/p/5406487.html
Copyright © 2011-2022 走看看