@Chilling
2017-03-05T11:34:34.000000Z
字数 4389
阅读 865
LCA
树链剖分
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 , indicating there are T test cases.
For each test case, the first will line contain two integers and , indicating the number of cities in byteland and the journey plans. Then N line followed, each line will contain three integer , and indicating there is a road cost z time connect the city and the city, the first roads will form a tree structure, indicating the original roads, and the line is the road built after Bob advised the king.
Then line followed, each line will contain two integer and , indicating there is a journey plan from the city to 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 line contains one integer indicating the time could saved in 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
题意: t组数据,有n个点,q次询问,1到n-1行表示最初x到y点距离为z,第n行为新加入的一条边a到b距离为c,每次询问:新加入边之后节省了多少路程,若没有则输出0。
分析:原图两点之间的距离可以用LCA求得,
dis[x,y]=dis[x]+dis[y]-2*dis[LCA(x,y)]
;若要经过新加入的边(a,b,c),起点x,终点y,那么一定有:从x→a,a→b,b→y或者x→b,b→a,a→y;ab间距离为c,其他两段距离用LCA求得。最后与原路程比较即可。
#include<stdio.h>
#include<vector>
#include<algorithm>
#include<string.h>
const int maxn=1e5+5;
using namespace std;
int n,q;
int dep[maxn],dis[maxn];
int fa[maxn][15];
struct node
{
int en,val;
node(int enn=0,int vall=0)
{
en=enn;
val=vall;
}
};
vector<node> V[maxn];
void clr()
{
memset(dep,0,sizeof(dep));
memset(dis,0,sizeof(dis));
memset(fa,0,sizeof(fa));
for(int i=0;i<=n;i++)
V[i].clear();
}
void dfs(int u,int f,int d)
{
fa[u][0]=f;
for(int i=1;i<15;i++)
fa[u][i]=fa[fa[u][i-1]][i-1];
dep[u]=d;
for(int i=0;i<V[u].size();i++)
{
node v=V[u][i];
if(v.en==f) continue;
dis[v.en]=dis[u]+v.val;
dfs(v.en,u,d+1);
}
}
int LCA(int u,int v)
{
if(dep[u]>dep[v])
swap(u,v);
for(int i=0;i<15;i++)
if((dep[v]-dep[u])>>i&1)
v=fa[v][i];
if(u==v) return u;
for(int i=14;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 t,o=0;
int x,y,z;
int a,b,c;
scanf("%d",&t);
while(t--)
{
clr();
scanf("%d%d",&n,&q);
for(int i=1;i<n;i++)
{
scanf("%d%d%d",&x,&y,&z);
V[x].push_back(node(y,z));
V[y].push_back(node(x,z));
}
dfs(1,0,1);
scanf("%d%d%d",&a,&b,&c);
printf("Case #%d:\n",++o);
while(q--)
{
scanf("%d%d",&x,&y);
int d1=dis[x]+dis[y]-2*dis[LCA(x,y)];
int d2=dis[x]+dis[a]-2*dis[LCA(x,a)]+dis[y]+dis[b]-2*dis[LCA(y,b)]+c;
int d3=dis[x]+dis[b]-2*dis[LCA(x,b)]+dis[y]+dis[a]-2*dis[LCA(y,a)]+c;
d2=min(d2,d3);
printf("%d\n",d1-d2<0?0:d1-d2);
}
}
return 0;
}
#include<stdio.h>
#include<vector>
#include<string.h>
#include<algorithm>
using namespace std;
const int maxn=1e5+5;
int n,q;
int dis[maxn];
int siz[maxn],dep[maxn],fa[maxn],son[maxn];
int top[maxn];
struct node
{
int en,val;
node(int enn=0,int vall=0)
{
en=enn;
val=vall;
}
};
vector<node> V[maxn];
void clr()
{
memset(dis,0,sizeof(dis));
memset(dep,0,sizeof(dep));
memset(fa,0,sizeof(fa));
memset(son,0,sizeof(son));
for(int i=0;i<=n;i++)
V[i].clear();
}
void dfs1(int u,int f,int d)
{
dep[u]=d;
fa[u]=f;
siz[u]=1;
for(int i=0;i<V[u].size();i++)
{
node v=V[u][i];
if(v.en==f) continue;
dis[v.en]=dis[u]+v.val;
dfs1(v.en,u,d+1);
if(siz[v.en]>siz[son[u]])
son[u]=v.en;
siz[u]+=siz[v.en];
}
}
void dfs2(int u,int f,int id)
{
top[u]=id;
if(!son[u]) return;
dfs2(son[u],u,id);
for(int i=0;i<V[u].size();i++)
{
node v=V[u][i];
if(v.en==f||v.en==son[u]) continue;
dfs2(v.en,u,v.en);
}
}
int LCA(int u,int v)
{
while(top[u]!=top[v])
{
if(dep[top[u]]<dep[top[v]])
swap(u,v);
u=fa[top[u]];
}
if(dep[u]<dep[v])
swap(u,v);
return v;
}
int main()
{
int t,o=0;
int x,y,z;
int a,b,c;
scanf("%d",&t);
while(t--)
{
clr();
scanf("%d%d",&n,&q);
for(int i=1;i<n;i++)
{
scanf("%d%d%d",&x,&y,&z);
V[x].push_back(node(y,z));
V[y].push_back(node(x,z));
}
dfs1(1,0,1);
dfs2(1,0,1);
scanf("%d%d%d",&a,&b,&c);
printf("Case #%d:\n",++o);
while(q--)
{
scanf("%d%d",&x,&y);
int d1=dis[x]+dis[y]-2*dis[LCA(x,y)];
int d2=dis[x]+dis[a]-2*dis[LCA(x,a)]+dis[y]+dis[b]-2*dis[LCA(y,b)]+c;
int d3=dis[x]+dis[b]-2*dis[LCA(x,b)]+dis[y]+dis[a]-2*dis[LCA(y,a)]+c;
d2=min(d2,d3);
printf("%d\n",d1-d2<0?0:d1-d2);
}
}
return 0;
}