zoj 3195 Design the city lca倍增

题目链接

给一棵树, m个询问, 每个询问给出3个点, 求这三个点之间的最短距离。

其实就是两两之间的最短距离加起来除2.

倍增的lca模板

#include <iostream>
#include <vector>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <map>
#include <set>
#include <string>
#include <queue>
#include <stack>
#include <bitset>
using namespace std;
#define pb(x) push_back(x)
#define ll long long
#define mk(x, y) make_pair(x, y)
#define lson l, m, rt<<1
#define mem(a) memset(a, 0, sizeof(a))
#define rson m+1, r, rt<<1|1
#define mem1(a) memset(a, -1, sizeof(a))
#define mem2(a) memset(a, 0x3f, sizeof(a))
#define rep(i, n, a) for(int i = a; i<n; i++)
#define fi first
#define se second
typedef pair<int, int> pll;
const double PI = acos(-1.0);
const double eps = 1e-8;
const int mod = 1e9+7;
const int inf = 1061109567;
const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} };
const int maxn = 1e5+5;
int head[maxn*2], num, dis[maxn], f[maxn], p[maxn][20], deep[maxn], n;
struct node
{
    int to, nextt, w;
}e[maxn*2];
void add(int u, int v, int w) {
    e[num].to = v, e[num].w = w, e[num].nextt = head[u], head[u] = num++;
}
void init() {
    num = 0;
    mem1(head);
    mem1(p);
}
void dfs(int u, int fa) {
    f[u] = fa;
    for(int i = head[u]; ~i; i = e[i].nextt) {
        int v = e[i].to;
        if(v == fa)
            continue;
        dis[v] = dis[u]+e[i].w;
        deep[v] = deep[u]+1;
        dfs(v, u);
    }
}
void lca_init()
{
    int i,j;
    for(i = 1; i<=n; i++)
        p[i][0] = f[i];
    for(j = 1; (1<<j)<=n; j++) {
        for(i = 1; i<=n; i++) {
            if(p[i][j-1] != -1)
                p[i][j] = p[p[i][j-1]][j-1];
        }
    }
}
int lca(int a,int b)
{
    int i,j;
    if(deep[a]<deep[b])
        swap(a, b);
    for(i = 0; (1<<i)<=deep[a]; i++);
        i--;
    for(j = i; j>=0; j--)
        if(deep[a]-(1<<j)>=deep[b])
            a = p[a][j];
    if(a == b)
        return a;
    for(j = i; j>=0; j--)
    {
        if(p[a][j] != -1 && p[a][j] != p[b][j])
        {
            a = p[a][j];
            b = p[b][j];
        }
    }
    return f[a];
}
int main()
{
    int x, y, m, w, z, ok = 0;
    while(cin>>n) {
        if(ok)
            puts("");
        ok = 1;
        init();
        for(int i = 0; i<n-1; i++) {
            scanf("%d%d%d", &x, &y, &w);
            add(x, y, w);
            add(y, x, w);
        }
        dfs(0, -1);
        lca_init();
        cin>>m;
        while(m--) {
            scanf("%d%d%d", &x, &y, &z);
            int ans = 0;
            ans += dis[x]+dis[y]-2*dis[lca(x,y)];
            ans += dis[x]+dis[z]-2*dis[lca(x,z)];
            ans += dis[y]+dis[z]-2*dis[lca(y,z)];
            printf("%d\n", ans/2);
        }
    }
    return 0;
}
时间: 2024-12-09 19:23:22

zoj 3195 Design the city lca倍增的相关文章

ZOJ 3195 Design the city LCA

题目:http://www.icpc.moe/onlinejudge/showProblem.do?problemCode=3195 题意:给定一个树,求三点之间的距离 思路:假定三点为u, v, w,那么(dist[u,v] + dist[v,w] + dist[u,w]) / 2就是答案 总结:wa时不要灰心,也许你离ac不远了 #include<iostream> #include<cstdio> #include<cstring> #include<alg

ZOJ 3195 Design the city

倍增法在线LCA..... ZOJ Problem Set - 3195 Design the city Time Limit: 1 Second      Memory 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,

ZOJ 3195 Design the city(LCA变形)

题意:给定一棵树,求连接三点所需的最短距离. 思路:LCA变形,连接三点的最短距离可以转化为求任意两点距离之和的和再除以二. #include<cstdio> #include<cstring> #include<cmath> #include<cstdlib> #include<iostream> #include<algorithm> #include<vector> #include<map> #incl

ZOJ 3195 Design the city 题解

这个题目大意是: 有N个城市,编号为0~N-1,给定N-1条无向带权边,Q个询问,每个询问求三个城市连起来的最小权值. 多组数据 每组数据  1 < N < 50000  1 < Q < 70000: 一道多源最短路的题目,注意题目数据:N.Q都很大 不能考虑Floyd.SPFA.Dijkstra.Bellman-Ford等最短路算法 再看N-1条边,明显构成一棵树,最短路有且只有一条 很明显需要LCA.... 不懂LCA的点!我!点!我! 我们所熟知的LCA是求两个点的最短路,而

ZOJ Problem Set - 3195 Design the city 【Tarjan离线LCA】

题目:ZOJ Problem Set - 3195 Design the city 题意:给出一个图,求三点的连起来的距离. 分析:分别求出三点中任意两点的距离 / 2  = ans AC代码: #include <iostream> #include <cstdio> #include <cstring> #include <vector> using namespace std; #define N 50010 #define M 20010 struc

ZOJ Design the city LCA转RMQ

Design the city Time Limit: 1 Second      Memory 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

[zoj3195]Design the city(LCA)

解题关键:求树上三点间的最短距离. 解题关键:$ans = (dis(a,b) + dis(a,c) + dis(b,c))/2$ 1 //#pragma comment(linker, "/STACK:1024000000,1024000000") 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cstdlib> 6 #include<

算法笔记--lca倍增算法

算法笔记 模板: vector<int>g[N]; vector<int>edge[N]; int anc[20][N]; int deep[N]; int h[N]; void dfs(int o,int u,int w) { if(u!=o)deep[u]=deep[o]+1,h[u]=h[o]+w; for(int j=0;j<g[u].size();j++) { if(g[u][j]!=o) { anc[0][g[u][j]]=u; for(int i=1;i<

lca 在线算法 zoj 3195

题目链接:Design the city 题目大意是对给定3点,求这三个点只之间的最短距离.三个点两两组合求lca:dis[u]+dis[v]-dis[lca];将三个组合值相加除以2即为答案. RMQ算法学习:http://blog.csdn.net/liang5630/article/details/7917702 对于lca->RMQ的转化,可以参看巨巨写的ppt. 欧拉序列:euler[N]; 深度序列:depth[N]; #include <iostream> #include