Journey
Time Limit: 15000/3000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others)
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 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 |
Source
模板题。
RMQ+LCA在线算法。
#include <cstdio> #include <cstring> #include <vector> #include <cmath> #include <algorithm> using namespace std; const int MAXN=100005; typedef pair<int,int> P; vector<P> G[MAXN]; int depth[2*MAXN]; int vs[MAXN*2]; int pos[MAXN]; int dep,cnt; int d[MAXN]; void dfs(int u,int fa) { int temp=++dep; depth[++cnt]=temp; vs[temp]=u; pos[u]=cnt; for(int i=0;i<G[u].size();i++) { P now=G[u][i]; if(now.first==fa) continue; d[now.first]=d[u]+now.second; dfs(now.first,u); depth[++cnt]=temp; } } int dp[MAXN*2][20]; void init_rmq(int n) { for(int i=1;i<=n;i++) dp[i][0]=depth[i]; int m=floor(log(n*1.0)/log(2.0)); for(int j=1;j<=m;j++) for(int i=1;i<=n-(1<<j)+1;i++) dp[i][j]=min(dp[i][j-1],dp[i+(1<<(j-1))][j-1]); } int rmq(int a,int b) { int k=floor(log((b-a+1)*1.0)/log(2.0)); return min(dp[a][k],dp[b-(1<<k)+1][k]); } int LCA(int u,int v) { if(pos[u]>pos[v]) swap(u,v); int k=rmq(pos[u],pos[v]); return vs[k]; } int dist(int u,int v) { return d[u]+d[v]-2*d[LCA(u,v)]; } int main() { int T; scanf("%d",&T); for(int cas=1;cas<=T;cas++) { memset(0,sizeof(d),0); cnt=0; dep=0; int V,Q; scanf("%d%d",&V,&Q); for(int i=1;i<=V;i++) G[i].clear(); for(int i=1;i<=V-1;i++) { int u,v,t; scanf("%d%d%d",&u,&v,&t); G[u].push_back(P(v,t)); G[v].push_back(P(u,t)); } int nu,nv,nt; scanf("%d%d%d",&nu,&nv,&nt); dfs(1,0); init_rmq(cnt); printf("Case #%d: ",cas); while(Q--) { int u,v; scanf("%d%d",&u,&v); int d1=dist(u,v); int d2=min(dist(u,nu)+dist(v,nv),dist(u,nv)+dist(v,nu))+nt; if(d2>=d1) printf("0 "); else printf("%d ",d1-d2); } } return 0; }