题目链接:http://acm.uestc.edu.cn/#/problem/show/92
Journey
Time Limit: 15000/3000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others)
Bob has traveled to byteland, he find the N
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 Bobhas Q journey plan, give you the start city and destination city, please tell Bob how many time is savedby 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
test cases.
For each test case, the first will line contain two integers N
( 2≤N≤105 ) and Q ( 1≤Q≤105 ), indicatingthe number of cities in byteland and the journey plans. Then N line followed, each line will contain threeinteger x , y ( 1≤x,y≤N ) and z ( 1≤z≤1000 ) indicating there is a road cost z time connectthe 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 twointeger x and y ( 1≤x,y≤N ), indicating there is a journey plan from the xth city to ythcity.
Output
For each case, you should first output Case #t:
in a single line, where
t
journey plan.
Sample input and output
Sample Input | Sample Output |
---|---|
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 | Case #1: 0 2 0 2 2 |
题意是给一棵树,然后在树上再加入一条边,问加入边之后询问的a b两点间的路程减少了多少
对于所有的点,我们可以分为环上的点和非环上的点组成
而非环上的点减少的路程是有它们在环上的父亲节点缩短的路程决定的
即A B缩短的距离 是 F[A] F[B]缩短的距离
而对于环上的点,我们可以指定新加入的XY边上的Y点为相对点
求出没有加入最后一条边时,所有点到 Y点的距离 Li
加入最后一条边后 我们找出环上的点 其中必然包括Y点 此时,Y点为环上点组成的树(不包括最后一条边)的根节点,而任意两点u v的距离则为 ans1= |Lu-Lv|
然后对与环上的点 求出加入最后一条边后到Y的新距离 即Y点此时只能与X点相连,不能与另一点X`相连
求出新的距离NewLi 则加入边后环上点到Y点的距离为 ans2= |NewLU-NewLv|
那么 缩短的路程就为 ans1-ans2>0?(ans1-ans2):0
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int N=1e5+50;
struct node
{
int u,v,w,next;
} e[N*2],ee[N];
int tol,head[N];
int lenx[N],leny[N];
int pre[N];
int newy[N];
int flag[N],hah[N];
int n,m;
int x,y,len;
void add(int u,int v,int w)
{
e[tol].u=u;
e[tol].v=v;
e[tol].w=w;
e[tol].next=head[u];
head[u]=tol++;
e[tol].v=u;
e[tol].u=v;
e[tol].w=w;
e[tol].next=head[v];
head[v]=tol++;
}
void bfs()
{
queue<int >q;
q.push(y);
memset(leny,-1,sizeof(leny));
memset(lenx,-1,sizeof(lenx));
leny[y]=0;
newy[y]=0;
lenx[x]=0;
while(q.size())
{
int st=q.front();
q.pop();
for(int i=head[st]; i!=-1; i=e[i].next)
{
int v=e[i].v;
if(v==st) continue ;
if(leny[v]==-1)
{
leny[v]=leny[st]+e[i].w;
newy[v]=leny[v];
q.push(v);
}
}
}
q.push(x);
while(q.size())
{
int st=q.front();
q.pop();
for(int i=head[st]; i!=-1; i=e[i].next)
{
int v=e[i].v;
if(v==st) continue ;
if(lenx[v]==-1)
{
lenx[v]=lenx[st]+e[i].w;
q.push(v);
}
}
}
}
void bfs_huan()
{
memset(flag,-1,sizeof(flag));
queue<int>q;
q.push(x);
while(q.size())
{
int st=q.front();
q.pop();
for(int i=head[st]; i!=-1; i=e[i].next)
{
int v=e[i].v;
if(v==pre[st]) continue ;
if(pre[v]==-1)
{
pre[v]=st;
q.push(v);
}
else
{
int vv=v;
int pp=st;
while(vv!=-1)
{
vv=pre[vv];
pre[v] = pp;
pp=v;
v=vv;
}
flag[x]=1;
hah[1]=x;
int l=2;
for(int j=pre[x]; j!=x; j=pre[j])
{
hah[l]=j;
flag[j]=l++;
}
return ;
}
}
}
}
void bfs_newy()
{
queue<int>q;
q.push(y);
newy[y]=0;
while(q.size())
{
int st=q.front();
q.pop();
for(int i=head[st];i!=-1;i=e[i].next)
{
int v=e[i].v;
if(flag[v]==-1) continue ;
if(newy[v]>newy[st]+e[i].w)
{
newy[v]=newy[st]+e[i].w;
q.push(v);
}
}
}
}
void bfs_flag()
{
queue<int>q;
for(int i=1;i<=n;i++)
if(flag[i]!=-1)
q.push(i);
while(q.size())
{
int st=q.front();
q.pop();
for(int i=head[st];i!=-1;i=e[i].next)
{
int v=e[i].v;
if(flag[v]==-1)
{
flag[v]=flag[st];
q.push(v);
}
}
}
}
int main()
{
int t,tt=1;
scanf("%d",&t);
while(t--)
{
printf("Case #%d:\n",tt++);
tol=0;
memset(head,-1,sizeof(head));
memset(pre,-1,sizeof(pre));
scanf("%d%d",&n,&m);
for(int i=0; i<n-1; i++)
{
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
add(u,v,w);
}
scanf("%d%d%d",&x,&y,&len);
bfs();
add(x,n+1,len);
add(y,n+1,0);
newy[n+1]=len+10;
bfs_huan();
bfs_newy();
bfs_flag();
for(int i=0;i<m;i++)
{
int a,b;
scanf("%d%d",&a,&b);
if(flag[a]==flag[b])
{
printf("0\n");
continue ;
}
else
{
a=hah[flag[a]];
b=hah[flag[b]];
int len1=leny[a]-leny[b];
if(len1<0) len1=-len1;
int len2=newy[a]+newy[b];
//cout<<leny[a]<<"*"<<newy[a]<<endl;
// cout<<leny[b]<<"*"<<newy[b]<<endl;
len1=(len1-len2)>0?(len1-len2):(0);
printf("%d\n",len1);
}
}
}
return 0;
}