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:\n",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\n");
            else printf("%d\n",d1-d2);
        }
    }
    return 0;
}

 

 

posted on 2016-02-02 15:35  vCoders  阅读(368)  评论(0编辑  收藏  举报

导航