ZOJ 3195 Design the city(LCA 树上三点最短距离)

Design the city

Time Limit: 1000 msMemory Limit: 32768 KB

Cerror is the mayor of city HangZhou. As you may know, the traffic system of this city is so terrible, that there are traffic jams everywhere. Now, Cerror finds out that the main reason of them is the poor design of the roads distribution, and he want to change this situation.

In order to achieve this project, he divide the city up to N regions which can be viewed as separate points. He thinks that the best design is the one that connect all region with shortest road, and he is asking you to check some of his designs.

Now, he gives you an acyclic graph representing his road design, you need to find out the shortest path to connect some group of three regions.

Input

The input contains multiple test cases! In each case, the first line contian a interger N (1 < N < 50000), indicating the number of regions, which are indexed from 0 to N-1. In each of the following N-1 lines, there are three interger Ai, Bi, Li (1 < Li < 100) indicating there's a road with length Li between region Ai and region Bi. Then an interger Q (1 < Q < 70000), the number of group of regions you need to check. Then in each of the following Q lines, there are three interger Xi, Yi, Zi, indicating the indices of the three regions to be checked.

Process to the end of file.

Output

Q lines for each test case. In each line output an interger indicating the minimum length of path to connect the three regions.

Output a blank line between each test cases.

Sample Input

4
0 1 1
0 2 1
0 3 1
2
1 2 3
0 1 2
5
0 1 1
0 2 1
1 3 1
1 4 1
2
0 1 2
1 0 3

Sample Output

3
2

2
2

Author: HE, Zhuobin

题意:

 n 个点,n - 1条边,给出 m 次询问,询问连通三点的最短距离

思路:

a, b, c三点距离即(a, b的距离 + a, c的距离 + b, c的距离) /  2,举个栗子就明白了

tarjin实现:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int N = 5e4 + 10;
const int M = 7e4 + 10;

int n, m, dis[N], head[N], qu[M], tot, fa[N];
bool vis[N];

struct node
{
    int to, w, next;
}edge[N << 1];

struct query
{
    int u, v, lca, next;
}q[6 * M];

void init()
{
    tot = 0;
    memset(vis, 0, sizeof(vis));
    memset(head, -1, sizeof(head));
    memset(qu, -1, sizeof(qu));

}

void add(int u, int v, int w)
{
    edge[tot].to = v;
    edge[tot].next = head[u];
    edge[tot].w = w;
    head[u] = tot++;
}

void add2(int u, int v)
{
    q[tot].u = u;
    q[tot].v = v;
    q[tot].next = qu[u];
    qu[u] = tot++;
}

int Find(int x)
{
    if(fa[x] != x)
        fa[x] = Find(fa[x]);
    return fa[x];
}

void tarjin(int u)
{
    fa[u] = u;
    vis[u] = 1;
    for(int i = head[u]; ~i; i = edge[i].next)
    {
        int v = edge[i].to;
        if(!vis[v])
        {
            dis[v] = dis[u] + edge[i].w;
            tarjin(v);
            fa[v] = u;
        }
    }
    for(int i = qu[u]; ~i; i = q[i].next)
    {
        int v = q[i].v;
        if(vis[v])
        {
            q[i].lca = q[i ^ 1].lca = Find(v);
        }
    }
}

int main()
{
    int kcase = 0;
    while(~scanf("%d", &n))
    {
        init();
        int u, v, w;
        for(int i = 1; i < n; ++i)
        {
            scanf("%d%d%d", &u, &v, &w);
            add(u, v, w);
            add(v, u, w);
        }
        tot = 0;
        int a, b, c;
        scanf("%d", &m);
        for(int i = 1; i <= m; ++i)
        {
            scanf("%d%d%d", &a, &b, &c);
            add2(a, b);
            add2(b, a);
            add2(a, c);
            add2(c, a);
            add2(b, c);
            add2(c, b);
        }
        tarjin(0);
        if(kcase)
            cout<<'\n';
        kcase++;
        for(int i = 0; i < tot; i += 6)
        {
            int ans = 0, u, v, lca;
            u = q[i].u;
            v = q[i].v;
            lca = q[i].lca;
            ans += dis[u] + dis[v] - 2 * dis[lca];
            u = q[i + 2].u;
            v = q[i + 2].v;
            lca = q[i + 2].lca;
            ans += dis[u] + dis[v] - 2 * dis[lca];
            u = q[i + 4].u;
            v = q[i + 4].v;
            lca = q[i + 4].lca;
            ans += dis[u] + dis[v] - 2 * dis[lca];
            cout << ans / 2 << '\n';
        }
    }
    return 0;
}

树上倍增实现

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int N = 5e4 + 10;

//dis[i]:点i到根节点的距离
//fa[i][j]:节点i的第2^j个父亲,每个点最多2^(logN)个父亲,所以第二维开logN
//dep[i]:当前节点的深度
int n, m, dis[N], head[N], fa[N][21], tot, dep[N];
struct Edge
{
    int to, next, w;
}edge[N << 1];

void init()
{
    tot = 0;
    memset(dis, 0, sizeof(dis));
    memset(head, -1, sizeof(head));
    memset(fa, 0, sizeof(fa));
}

void add(int u, int v, int w)
{
    edge[tot].next = head[u];
    edge[tot].to = v;
    edge[tot].w = w;
    head[u] = tot++;
}

void dfs(int u, int father)   //当前节点和它的父亲
{
    dep[u] = dep[father] + 1;
    for(int i = 1; (1 << i) <= dep[u]; ++i)
    {
        if(fa[u][i - 1])
            fa[u][i] = fa[fa[u][i - 1]][i - 1];
        else break;   //如果该点没有第2^(i - 1)个父亲了,也不会有更远的父亲
    }
    for(int i = head[u]; ~i; i = edge[i].next)  //遍历相邻的所有点
    {
        int v = edge[i].to;
        if(v != father) // v 不是 u 的父亲,就是 u 的儿子
        {
            dis[v] = dis[u] + edge[i].w;    //更新距离
            fa[v][0] = u;   // v 的第2^0个父亲即第一个父亲是 u
            dfs(v, u);
        }
    }
}

int lca(int u, int v)
{
    if(dep[u] < dep[v]) //默认 u 比 v 深
        swap(u, v);
    for(int i = 20; i >= 0; --i)    //从大到小枚举使 x 和 y 到达同一层
    {
        if(dep[fa[u][i]] >= dep[v])
            u = fa[u][i];
        if(u == v)
            return u;
    }
    for(int i = 20; 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, a, b, c, kcase = 0;
    while(~scanf("%d", &n))
    {
        init();
        for(int i = 1; i < n; ++i)
        {
            scanf("%d%d%d", &u, &v, &w);
            add(u, v, w);
            add(v, u, w);
        }
        dfs(0, 0);  //选取1为根节点,1的父亲是0
        if(kcase) cout<<'\n';
        kcase++;
        scanf("%d", &m);
        while(m--)
        {
            scanf("%d%d%d", &a, &b, &c);
            int ans = dis[a] + dis[b] - 2 * dis[lca(a, b)] + dis[a] + dis[c] - 2 * dis[lca(a, c)] + dis[b] + dis[c] - 2 * dis[lca(b, c)];
            ans /= 2;
            cout<<ans<<'\n';
        }
    }
    return 0;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Discover the techniques behind beautiful design?by deconstructing designs to understand them, The term ?hacker? has been redefined to consist of anyone who has an insatiable curiosity as to how things work?and how they can try to make them better. This book is aimed at hackers of all skill levels and explains the classical principles and techniques behind beautiful designs by deconstructing those designs in order to understand what makes them so remarkable. Author and designer David Kadavy provides you with the framework for understanding good design and places a special emphasis on interactive mediums. You?ll explore color theory, the role of proportion and geometry in design, and the relationship between medium and form. Packed with unique reverse engineering design examples, this book inspires and encourages you to discover and create new beauty in a variety of formats., Breaks down and studies the classical principles and techniques behind the creation of beautiful design, Illustrates cultural and contextual considerations in communicating to a specific audience, Discusses why design is important, the purpose of design, the various constraints of design, and how today?s fonts are designed with the screen in mind, Dissects the elements of color, size, scale, proportion, medium, and form, Features a unique range of examples, including the graffiti in the ancient city of Pompeii, the lack of the color black in Monet?s art, the style and sleekness of the iPhone, and more, By the end of this book, you?ll be able to apply the featured design principles to your own web designs, mobile apps, or other digital work.
Robust design—that is, managing design uncertainties such as model uncertainty or parametric uncertainty—is the often unpleasant issue crucial in much multidisciplinary optimal design work. Recently, there has been enormous practical interest in strategies for applying optimization tools to the development of robust solutions and designs in several areas, including aerodynamics, the integration of sensing (e.g., laser radars, vision-based systems, and millimeter-wave radars) and control, cooperative control with poorly modeled uncertainty, cascading failures in military and civilian applications, multi-mode seekers/sensor fusion, and data association problems and tracking systems. The contributions to this book explore these different strategies. The expression "optimization-directed” in this book’s title is meant to suggest that the focus is not agonizing over whether optimization strategies identify a true global optimum, but rather whether these strategies make significant design improvements.... more on http:// springer.com/978-0-387-28263-3 Yes, please send me copies 7 Call: + 49 (0) 6221-345-4301 7 Fax: +49 (0) 6221-345-4229 7 Web: springer.com 7 Email: orders-hd-individuals@springer.com Springer Order Department PO Box 2485 Secaucus, NJ 07096-2485 USA Name Address Street Address (Sorry, we cannot deliver to P.O. boxes) City / State / ZIP-Code Date Signature Country Telephone / Email Methods of Payment Check/Money Order enclosed AmEx MasterCard VISA Card No. Exp. Date Order Now! 7 Call toll-free 1-800-SPRINGER 8:30 am – 5:30 pm ET 7 Fax your order to (201) 348-4505 7 Web springer.com 7 Email orders-ny@springer.com CA, MA, NJ, NY, and PA residents, please add sales tax. Canadian residents, please add 5% GST. Please add $5.00 for shipping one book and $1.00 for each additional book. Outside the US and Canada add $10.00 for first book, $5.00 for each additional book. All orders are processed upon receipt. If an order cannot be fulfilled within 90 days, payment will be refunded upon request. Prices are payable in US currency or its equivalent. Remember, your 30-day return privilege is always guaranteed. Pre-publication pricing: Unless otherwise stated, pre-pub prices are valid through the end of the third month following publication, and therefore are subject to change. Springer Customer Service Center GmbH Haberstrasse 7 69126 Heidelberg Germany All € and £ prices are net prices subject to local VAT, e.g. in Germany 7% VAT for books and 19% VAT for electronic products. Pre-publication pricing: Unless otherwise stated, pre-pub prices are valid through the end of the third month following publication, and therefore are subject to change. All prices exclusive of carriage charges. Prices and other details are subject to change without notice. All errors and omissions excepted. Please consult springer.com for information on postage. Please send orders to: Outside the Americas: "Robust Optimization-Directed Design" ISBN 978-0-387-28263-3

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值