cdoj 92 Journey tarjan/lca 树上点对距离
Journey
Time Limit: 1 Sec
Memory Limit: 256 MB
题目连接
http://acm.uestc.edu.cn/#/problem/show/92
Description
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 N−1 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(1≤T≤20), indicating there are T test cases.
For each test case, the first will line contain two integers N(2≤N≤105) and Q(1≤Q≤105), indicating the number of cities in byteland and the journey plans. Then N line followed, each line will contain three integer x, y(1≤x,y≤N) and z(1≤z≤1000) indicating there is a road cost z time connect the xth city and the yth city, the first N−1 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(1≤x,y≤N), 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
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
Sample Output
Case #1:
0
2
0
2
2
HINT
题意
给你一棵树,然后加了一条边,然后给Q次询问,问你这些点之间的最短距离缩短了多少
题解:
加了边之后,你走的方式就变成三种了,要么和原来一样,要么就是u-A-B-v,要么就是u-B-A-v这种
tarjan预处理一下距离跑一发就好了
@)1%KBO0HM418$J94$1R.jpg)
代码:
//qscqesze
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <cstdio>
#include <cmath>
#include <cstring>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <set>
#include <bitset>
#include <vector>
#include <sstream>
#include <queue>
#include <typeinfo>
#include <fstream>
#include <map>
#include <stack>
typedef long long ll;
using namespace std;
//freopen("D.in","r",stdin);
//freopen("D.out","w",stdout);
#define sspeed ios_base::sync_with_stdio(0);cin.tie(0)
#define maxn 200006
#define mod 1000000007
#define eps 1e-9
#define e exp(1.0)
#define PI acos(-1)
const double EP = 1E- ;
int Num;
//const int inf=0x7fffffff;
const ll inf=;
inline ll read()
{
ll x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
//***********************************************************
struct ndoe{
int v,w,next;
}ed[maxn*];
int dp[][maxn*],pos[maxn],dis[maxn],res[maxn],head[maxn],parent[maxn],vis[maxn];
int n,m,c,num,cnt,size;
void addedge(int u,int v,int w)
{
ed[num].v=v;
ed[num].w=w;
ed[num].next=head[u];
head[u]=num++;
}
int Find(int i)
{
if(i!=parent[i])
parent[i]=Find(parent[i]);
return parent[i];
}
void Union(int i,int j)
{
int x,y;
x=Find(i);
y=Find(j);
if(x!=y)
parent[x]=y;
}
int A,B,C,q;
void init()
{
int i,j,k;
n=read();q=read();
m=n-;
memset(head,-,sizeof(head));
memset(vis,,sizeof(vis));
for(i=;i<=n;i++)
parent[i]=i;
cnt=size=num=;
while(m--)
{
scanf("%d%d%d",&i,&j,&k);
addedge(i,j,k);
addedge(j,i,k);
Union(i,j);
}
A=read(),B=read(),C=read();
}
void dfs(int u,int dist)
{
int i,j;
vis[u]=;
dis[u]=dist;
pos[u]=cnt;
res[size]=u;
dp[][cnt++]=size++;
for(i=head[u];i!=-;i=ed[i].next)
{
j=ed[i].v;
if(!vis[j])
{
dfs(j,dist+ed[i].w);
dp[][cnt++]=dp[][pos[u]];
}
}
}
void rmq()
{
int i,j,k;
for(i=;(<<i)<=n;i++)
for(j=n-;j>=;j--)
{
k=(<<(i-));
dp[i][j]=dp[i-][j];
if(k+j<n)
dp[i][j]=min(dp[i][j],dp[i-][j+k]);
}
}
int cal(int i,int j)
{
int k;
if(i<j)
{
i^=j;
j^=i;
i^=j;
}
k=;
while((<<k)<=(i-j+))
k++;
k--;
k=min(dp[k][j],dp[k][i-(<<k)+]);
return res[k];
}
int Dis(int u,int v)
{
int k = cal(pos[u],pos[v]);
return dis[u]+dis[v]-dis[k]*;
}
int tot = ;
void solve()
{
int i,j,k;
for(i=;i<=n;i++)
if(!vis[i])
dfs(i,);
n=n*-;
rmq();
printf("Case #%d:\n",tot);
for(int i=;i<=q;i++)
{
int u=read(),v=read();
int P = Dis(u,v);
int PP1 = Dis(u,A)+C+Dis(B,v);
int PP2 = Dis(u,B)+C+Dis(A,v);
PP1 = min(PP1,PP2);
printf("%d\n",max(P-PP1,));
}
}
int main()
{
int t=read();
while(t--)
{
tot++;
init();
solve();
}
return ;
}
cdoj 92 Journey tarjan/lca 树上点对距离的更多相关文章
- CDOJ 92 – Journey 【LCA】
[题意]给出一棵树,有n个点(2≤N≤105),每条边有权值,现在打算新修一条路径,给出新路径u的起点v,终点和权值,下面给出Q(1≤Q≤105)个询问(a,b)问如果都按照最短路径走,从a到b节省了 ...
- CDOJ 92 Journey LCA乱搞
原题链接:http://acm.uestc.edu.cn/#/problem/show/92 题意: 给你一棵树,然后在树上连接一条边.现在有若干次询问,每次问你两个点(u,v)之间的距离在加那条边之 ...
- CDOJ 92 Journey(LCA&RMQ)
题目连接:http://acm.uestc.edu.cn/#/problem/show/92 题意:给定一棵树,最后给加一条边,给定Q次查询,每次查询加上最后一条边之后是否比不加这条边要近,如果近的话 ...
- poj 3417 Network(tarjan lca)
poj 3417 Network(tarjan lca) 先给出一棵无根树,然后下面再给出m条边,把这m条边连上,然后每次你能毁掉两条边,规定一条是树边,一条是新边,问有多少种方案能使树断裂. 我们设 ...
- 洛谷 P2783 有机化学之神偶尔会做作弊(Tarjan,LCA)
题目背景 LS中学化学竞赛组教练是一个酷爱炉石的人. 有一天他一边搓炉石一边监考,而你作为一个信息竞赛的大神也来凑热闹. 然而你的化竞基友却向你求助了. “第1354题怎么做”<--手语 他问道 ...
- Tarjan+LCA【洛谷P2783】 有机化学之神偶尔会做作弊
[洛谷P2783] 有机化学之神偶尔会做作弊 题目背景 XS中学化学竞赛组教练是一个酷爱炉石的人. 有一天他一边搓炉石一边监考,而你作为一个信息竞赛的大神也来凑热闹. 然而你的化竞基友却向你求助了. ...
- [BZOJ3307]:雨天的尾巴(LCA+树上差分+权值线段树)
题目传送门 题目描述: N个点,形成一个树状结构.有M次发放,每次选择两个点x,y对于x到y的路径上(含x,y)每个点发一袋Z类型的物品.完成所有发放后,每个点存放最多的是哪种物品. 输入格式: 第一 ...
- LCA UESTC 92 Journey
题目传送门 题意:先给一棵树,然后有一条额外的边,问u走到v从现在最短的路走和原来不加边走的路节省了多少距离 分析:首先跑不加边的树的LCA,这样能求出任意两点的距离,那么现在x和y多连了一条边,如果 ...
- [luogu P3128][USACO15DEC]Max Flow [LCA][树上差分]
题目描述 Farmer John has installed a new system of pipes to transport milk between the stalls in his b ...
随机推荐
- Ubuntu安装node.js
通过PPA安装Node.js sudo apt-get install python-software-properties sudo add-apt-repository ppa:chris-lea ...
- FormsAuthentication 登录兼容 IE11 保存cookie
现象:使用FormsAuthentication进行登录验证,在IE11客户端无法保存cookie 解决方法:在web.config中的forms中增加cookieless="UseCook ...
- 【转】Android学习基础自定义Checkbox组件
原文网址:http://forum.maiziedu.com/thread-515-1-1.html heckbox组件是一种可同时选中多项的基础控件,即复选框,在android学习中,Checkbo ...
- FireFox、chrome通过插件使用IE内核,IE Tab v2
fireFox 插件管理中 搜索IE tab 找到ieTab v2 安装后,添加网站规则就可以用. chrome 去ietab.net 下载 *.crx文件, 打开插件管理界面, 拖拽 *.cr ...
- Android中Toast的用法简介
转自:http://www.cnblogs.com/GnagWang/archive/2010/11/26/1888762.html Toast是Android中用来显示显示信息的一种机制,和Dial ...
- android数据库(随apk一起发布数据库)
读取数据库+数据库版本更新 注意: a, 将随apk发布的数据库放在android工程下/res/raw路径下. b, 数据库文件存到手机上时,路径在/data/data/你的包名/databases ...
- [Bhatia.Matrix Analysis.Solutions to Exercises and Problems]ExI.5.10
Every $k\times k$ positive matrix $A=(a_{ij})$ can be realised as a Gram matrix, i.e., vectors $x_j$ ...
- EF5.0修改实体的时候,出现“对一个或多个实体的验证失败。有关详细信息,请参见“EntityValidationErrors”属性这个错误
对于这个错误,要在SaveChanges前关闭验证实体有效性(ValidateOnSaveEnabled)这个开关 db.Configuration.ValidateOnSaveEnabled = f ...
- uva11732 strcmp() Anyone?
题意:给出多个字符串,两两配对,求总配对次数. 思路:如果两个字符串一样,ans=strlen(字符串)*2+2,如果不同,ans=公共前缀长度*2+1:用左儿子右兄弟建字典树.插入一个字符计算一次. ...
- CSU 1515 Sequence (莫队算法)
题意:给n个数,m个询问.每个询问是一个区间,求区间内差的绝对值为1的数对数. 题解:先离散化,然后莫队算法.莫队是离线算法,先按按询问左端点排序,在按右端点排序. ps:第一次写莫队,表示挺简单的, ...