zoukankan      html  css  js  c++  java
  • UESTC(LCA应用:求两点之间的距离)

    Journey

    Time Limit: 15000/3000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others)

    Bob has traveled to byteland, he find the N cities in byteland formed a tree structure, a tree structure is very special structure, there is exactly one path connecting each pair of nodes, and a tree with N nodes has N1 edges.

    As a traveler, Bob wants to journey between those N cities, and he know the time each road will cost. he advises the king of byteland building a new road to save time, and then, a new road was built. Now Bob has Q journey plan, give you the start city and destination city, please tell Bob how many time is saved by add a road if he always choose the shortest path. Note that if it's better not journey from the new roads, the answer is 0.

    Input

    First line of the input is a single integer T(1T20), indicating there are T test cases.

    For each test case, the first will line contain two integers N(2N105) and Q(1Q105), indicating the number of cities in byteland and the journey plans. Then N line followed, each line will contain three integer xy(1x,yN) and z(1z1000) indicating there is a road cost z time connect the xth city and the yth city, the first N1 roads will form a tree structure, indicating the original roads, and the Nth line is the road built after Bob advised the king. Then Q line followed, each line will contain two integer x and y(1x,yN), indicating there is a journey plan from the xth city to yth city.

    Output

    For each case, you should first output Case #t: in a single line, where t indicating the case number between 1 and T, then Q lines followed, the ith line contains one integer indicating the time could saved in ith journey plan.

    Sample input and output

    Sample InputSample Output
    1
    5 5
    1 2 3
    2 3 4
    4 1 5
    3 5 1
    3 1 5
    1 2
    1 3
    2 5
    3 4
    4 5
    
    Case #1:
    0
    2
    0
    2
    2

    Source

    Sichuan State Programming Contest 2012

    模板题。

    RMQ+LCA在线算法。

    #include <cstdio>
    #include <cstring>
    #include <vector>
    #include <cmath>
    #include <algorithm>
    using namespace std;
    const int MAXN=100005;
    typedef pair<int,int> P;
    vector<P> G[MAXN];
    int depth[2*MAXN];
    int vs[MAXN*2];
    int pos[MAXN];
    int dep,cnt;
    int d[MAXN];
    void dfs(int u,int fa)
    {
        int temp=++dep;
        depth[++cnt]=temp;
        vs[temp]=u;
        pos[u]=cnt;
        for(int i=0;i<G[u].size();i++)
        {
            P now=G[u][i];
            if(now.first==fa)    continue;
            d[now.first]=d[u]+now.second;
            dfs(now.first,u);
            depth[++cnt]=temp;
        }
    }
    int dp[MAXN*2][20];
    void init_rmq(int n)
    {
        for(int i=1;i<=n;i++)    dp[i][0]=depth[i];
        
        int m=floor(log(n*1.0)/log(2.0));
        for(int j=1;j<=m;j++)
            for(int i=1;i<=n-(1<<j)+1;i++)
                dp[i][j]=min(dp[i][j-1],dp[i+(1<<(j-1))][j-1]);
    }
    int rmq(int a,int b)
    {
        int k=floor(log((b-a+1)*1.0)/log(2.0));
        return min(dp[a][k],dp[b-(1<<k)+1][k]);
    }
    int LCA(int u,int v)
    {
        if(pos[u]>pos[v])    swap(u,v);
        int k=rmq(pos[u],pos[v]);
        return vs[k];
    }
    int dist(int u,int v)
    {
        return d[u]+d[v]-2*d[LCA(u,v)];
    }
    int main()
    {
        int T;
        scanf("%d",&T);
        for(int cas=1;cas<=T;cas++)
        {
            memset(0,sizeof(d),0);
            cnt=0;
            dep=0;
            int V,Q;
            scanf("%d%d",&V,&Q);
            for(int i=1;i<=V;i++)    G[i].clear();
            for(int i=1;i<=V-1;i++)
            {
                int u,v,t;
                scanf("%d%d%d",&u,&v,&t);
                G[u].push_back(P(v,t));
                G[v].push_back(P(u,t));    
            }
            int nu,nv,nt;
            scanf("%d%d%d",&nu,&nv,&nt);
            dfs(1,0);
            init_rmq(cnt);
            printf("Case #%d:
    ",cas);
            while(Q--)
            {
                int u,v;
                scanf("%d%d",&u,&v);
                int d1=dist(u,v);
                int d2=min(dist(u,nu)+dist(v,nv),dist(u,nv)+dist(v,nu))+nt;    
                if(d2>=d1)    printf("0
    ");
                else printf("%d
    ",d1-d2);
            }
        }
        return 0;
    }
  • 相关阅读:
    Python学习之路—2018/6/27
    Python学习之路—2018/6/26
    python面试315问
    day4(css优先级)
    date3(form表单,今天html结束,css)
    date2(html)
    day1
    mysql数据库(7day)
    mysql数据库(day6)索引,ORM框架
    mysql数据库(day5)-视图,触发器,存储过程
  • 原文地址:https://www.cnblogs.com/program-ccc/p/5177694.html
Copyright © 2011-2022 走看看