zoj 3195

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=3320

离线算法RE了..

#include<stdio.h>
#include<iostream>
#include<string.h>
#include<math.h>
#include<algorithm>
using namespace std;
const int N = 50005;
const int M =100005;
struct Edge{
    int u,v,w,next;
}e[2*N];
struct Q_Edge{
    int u,v,next,lca;
}eq[2*M];
int head[N];
int _head[N];
int dis[N];
int vis[N];
int ances[N];
int father[N];
void addedge(int u,int v,int w,int &k){
    e[k].u = u;e[k].v = v;e[k].w= w;
    e[k].next = head[u];head[u]=k++;
}
void add_qedge(int u,int v,int &k){
    eq[k].u = u;eq[k].v = v;eq[k].lca = -1;
    eq[k].next = _head[u];_head[u]=k++;
}
int _find(int u){
    if(u==father[u]) return father[u];
    return father[u] = _find(father[u]);
}
void unions(int u,int v){
    int x = _find(u),y = _find(v);
    father[x]=y;
}
void Targin(int u){
    vis[u] = true;
    ances[u]=father[u] = u;
    for(int k = head[u];k!=-1;k=e[k].next){
        if(!vis[e[k].v]){
            int v = e[k].v,w = e[k].w;
            dis[v] = dis[u]+w;
            Targin(v);
            unions(v,u);
            ances[_find(u)] = u;
        }
    }
    for(int k = _head[u];k!=-1;k=eq[k].next){
        if(vis[eq[k].v]){
            int v = eq[k].v;
            eq[k].lca = eq[k^1].lca = ances[_find(v)];
        }
    }
}
int main()
{
    int n;
    while(scanf("%d",&n)!=EOF){

        memset(head,-1,sizeof(head));
        memset(_head,-1,sizeof(_head));

        int tot=0;
        for(int i=1;i<n;i++){
            int u,v,w;
            scanf("%d%d%d",&u,&v,&w);
            addedge(u,v,w,tot);
            addedge(v,u,w,tot);
        }
        tot = 0;
        int m;
        scanf("%d",&m);
        for(int i=0;i<m;i++){
            int a,b,c;
            scanf("%d%d%d",&a,&b,&c);
            add_qedge(a,b,tot);
            add_qedge(b,a,tot);
            add_qedge(a,c,tot);
            add_qedge(c,a,tot);
            add_qedge(b,c,tot);
            add_qedge(c,b,tot);

        }
        memset(vis,0,sizeof(vis));
        dis[0]=0;
        Targin(0);
        int a[3];
        for(int i=0;i<m;i++){
            int s = i*6;
            a[0] = dis[eq[s].u]+dis[eq[s].v]-2*dis[eq[s].lca];  ///a->b
            a[1] = dis[eq[s+2].u]+dis[eq[s+2].v]-2*dis[eq[s+2].lca]; ///a->c
            a[2] = dis[eq[s+4].u]+dis[eq[s+4].v]-2*dis[eq[s+4].lca]; ///b->c
            //sort(a,a+3);
            printf("%d\n",(a[2]+a[1]+a[0])/2);

        }
        printf("\n");
    }

}
时间: 2024-10-10 01:02:10

zoj 3195的相关文章

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

题目: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变形)

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

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 <s

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 3195 LCA转RMQ

点击打开链接 题意:输入n,接下来n-1行,每行a,b,c代表a与b有一条权值为c的边,双向边,m次询问,问最短的距离使a,b,c可以联通 思路:LCA的模版题,没什么好说的,看理论的话网上好多本弱就不说了,代码有注释,有助于理解 #include <vector> #include <stdio.h> #include <string.h> #include <stdlib.h> #include <iostream> #include <

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

HDU 2586 LCA转RMQ

点击打开链接 题意:就是问两个节点间的距离 思路:又切了一道模版水题,不解释了,看不懂变量含义的可以看我写的这篇,解释的比较详细ZOJ 3195 #include <vector> #include <stdio.h> #include <string.h> #include <stdlib.h> #include <iostream> #include <algorithm> using namespace std; typedef

最近公共祖先LCA(Tarjan算法)的思考和算法实现——转载自Vendetta Blogs

最近公共祖先LCA(Tarjan算法)的思考和算法实现 LCA 最近公共祖先 Tarjan(离线)算法的基本思路及其算法实现 小广告:METO CODE 安溪一中信息学在线评测系统(OJ) //由于这是第一篇博客..有点瑕疵...比如我把false写成了flase...看的时候注意一下! //还有...这篇字比较多 比较杂....毕竟是第一次嘛 将就将就 后面会重新改!!! 首先是最近公共祖先的概念(什么是最近公共祖先?): 在一棵没有环的树上,每个节点肯定有其父亲节点和祖先节点,而最近公共祖先