这个题目大意是:

    有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是求两个点的最短路,而该题稍微变形,要求三个点

    所以我们可以两两求LCA,然后把三个dist值加起来除以二

    而两点的dist值是这样算的:dist[a]+dist[b]-2*dist[LCA(a,b)]

    代码如下:

    

 #include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 200010
#define M 600010
using namespace std;
struct DATA
{
int from,to,dis,next,i;
}road[N],ques[M];
int dist[N],head1[N],head2[M],f[N],ans[M],n,q,len1,len2,fun=;
bool vis[N],book[M],found[N];
void add1(int a,int b,int c,int i)
{
len1++;
road[len1].from=a;
road[len1].to=b;
road[len1].dis=c;
road[len1].i=i;
road[len1].next=head1[a];
head1[a]=len1;
}
void add2(int a,int b,int c,int i)
{
len2++;
ques[len2].from=a;
ques[len2].to=b;
ques[len2].dis=c;
ques[len2].i=i;
ques[len2].next=head2[a];
head2[a]=len2;
}
int find(int x){return f[x]==x?x:f[x]=find(f[x]);}
void marge(int x,int y){if(find(x)!=find(y)) f[y]=x;}
void Tarjan(int u,int dev)
{
int e=head1[u],a,b,i,tmp;
while(e!=-)
{
a=road[e].to;
i=road[e].i;
tmp=dev+road[e].dis;
if(!vis[a] && !found[i])
{
found[i]=;
dist[a]=tmp;
Tarjan(a,tmp);
vis[a]=;
marge(u,a);
}
e=road[e].next;
}
e=head2[u];
while(e!=-)
{
a=ques[e].to;
i=ques[e].i;
if(vis[a] && !book[i])
{
book[i]=;
b=find(a);
ans[i]=dist[a]+dist[u]-*dist[b];
}
e=ques[e].next;
}
return ;
}
void init()
{
int i;
len1=,len2=;
for(i=;i<N;i++)
{
road[i].from=road[i].to=road[i].dis=road[i].next=road[i].i=;
f[i]=i;
}
for(i=;i<M;i++)
ques[i].from=ques[i].to=ques[i].dis=ques[i].next=ques[i].i=;
memset(head1,-,sizeof(head1));
memset(head2,-,sizeof(head2));
memset(dist,,sizeof(dist));
memset(vis,,sizeof(vis));
memset(book,,sizeof(book));
memset(found,,sizeof(found));
memset(ans,,sizeof(ans));
return ;
}
int main()
{
// freopen("1.in","r",stdin);
// freopen("test.out","w",stdout);
while(~scanf("%d",&n))
{
if(fun++) printf("\n");
init();
int i,a,b,c,tmp=;
for(i=;i<n;i++)
{
scanf("%d%d%d",&a,&b,&c);
add1(a,b,c,i);
add1(b,a,c,i);
tmp=min(min(a,b),tmp);
}
scanf("%d",&q);
for(i=;i<=q;i++)
{
scanf("%d%d%d",&a,&b,&c);
add2(a,b,,i);
add2(b,a,,i);
add2(a,c,,i+q);
add2(c,a,,i+q);
add2(b,c,,i+*q);
add2(c,b,,i+*q);
}
Tarjan(tmp,);
for(i=;i<=q;i++)
printf("%d\n",(ans[i]+ans[i+q]+ans[i+*q])/);
}
return ;
}

ZOJ 3195 Design the city 题解的更多相关文章

  1. zoj——3195 Design the city

    Design the city Time Limit: 1 Second      Memory Limit: 32768 KB Cerror is the mayor of city HangZho ...

  2. ZOJ 3195 Design the city (LCA 模板题)

    Cerror is the mayor of city HangZhou. As you may know, the traffic system of this city is so terribl ...

  3. zoj 3195 Design the city LCA Tarjan

    题目链接 : ZOJ Problem Set - 3195 题目大意: 求三点之间的最短距离 思路: 有了两点之间的最短距离求法,不难得出: 对于三个点我们两两之间求最短距离 得到 d1 d2 d3 ...

  4. ZOJ 3195 Design the city LCA转RMQ

    题意:给定n个点,下面n-1行 u , v ,dis 表示一条无向边和边权值,这里给了一颗无向树 下面m表示m个询问,问 u v n 三点最短距离 典型的LCA转RMQ #include<std ...

  5. ZOJ - 3195 Design the city

    题目要对每次询问将一个树形图的三个点连接,输出最短距离. 利用tarjan离线算法,算出每次询问的任意两个点的最短公共祖先,并在dfs过程中求出离根的距离.把每次询问的三个点两两求出最短距离,这样最终 ...

  6. zoj 3195 Design the city lca倍增

    题目链接 给一棵树, m个询问, 每个询问给出3个点, 求这三个点之间的最短距离. 其实就是两两之间的最短距离加起来除2. 倍增的lca模板 #include <iostream> #in ...

  7. ZOJ Design the city LCA转RMQ

    Design the city Time Limit: 1 Second      Memory Limit: 32768 KB Cerror is the mayor of city HangZho ...

  8. ZOJ3195 Design the city [2017年6月计划 树上问题04]

    Design the city Time Limit: 1 Second      Memory Limit: 32768 KB Cerror is the mayor of city HangZho ...

  9. xtu summer individual 1 C - Design the city

    C - Design the city Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%lld & %llu D ...

随机推荐

  1. 理解margin负值

    效果 上和左方的margin负值使元素向上和左方向移动,如果该元素position不是absolute或fixed,这还会导致之后的元素也向上,左移 下和右方的margin负值会缩小下和右方的空间,使 ...

  2. Java并发之线程异常捕获

    由于线程的本质特性,使得你不能捕获从线程中逃逸的异常,如: import java.util.concurrent.ExecutorService; import java.util.concurre ...

  3. oracle数据库命令-持续更新

    一.系统命令 登录 dba用户命令 sqlplus / as sysdba 2. 用户命令 删除用户 DROP USER **** CASCADE; DROP SCHEMA **** CASCADE; ...

  4. MacOS无法登录App Store修复

    MacOS无法登录App Store修复 2017-03-10 21:13:39  by:SemiconductorKING 先上图: 惨红色的提示信息,把你拒之App Store门外,但是对之放弃. ...

  5. 专题:DUILIB Win32 透明效果

    Win32 透明效果相关基础知识 Layered Windows 分层窗口.这是Windows2000开始引入的概念,重新定义了窗口的Hit Testing方法,以前都是把窗口按rectangle的方 ...

  6. Struts2学习笔记⑥

    在微信读书上在看一本李刚写的Struts 2.X权威指南 (好像叫这个)的书,可以看得出来作者的开发经验还是很充足的,但是觉得他的尺度和顺序没有把握好,他自己说拦截器是数据校验.国际化的基础-完了还把 ...

  7. 3297: [USACO2011 Open]forgot

    3297: [USACO2011 Open]forgot Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 69  Solved: 51[Submit][ ...

  8. servlet匹配规则和顺序

    1.  写法 ①完全匹配:以“/”开头,以字母(非“*”)结束    如:<url-pattern>/test/list.do</url-pattern> ②目录匹配:以“/” ...

  9. latex lstlisting

    转自 http://blog.csdn.net/lydyangliu/article/details/9208635 \usepackage{graphicx}\usepackage{xcolor}\ ...

  10. 配置adb环境变量

    作为Android开发人员,会经常使用adb命令来进行push.pull.install.看数据库等.记录一下adb配置流程,以备后用. 在没有配置adb之前,我们打开Windows命令处理程序(cm ...