COGS——T1588. [USACO FEB04]距离咨询
http://cogs.pro/cogs/problem/problem.php?pid=1588
★★ 输入文件:dquery.in
输出文件:dquery.out
简单对比
时间限制:1 s 内存限制:256 MB
【题目描述】
农夫约翰有N(2<=N<=40000)个农场,标号1到N。M(2<=M<=40000)条的不同的垂直或水平的道路连结着农场,道路的长度不超过1000.这些农场的分布就像下面的地图一样,图中农场用F1..F7表示:
每个农场最多能在东西南北四个方向连结4个不同的农场。此外,农场只处在道路的两端。道路不会交叉而且每对农场间有且仅有一条路径。邻居鲍伯要约翰来导航,但约翰丢了农场的地图,他只得从电脑的备份中修复率。每一条道路的信息如下:
从农场23往南经距离10到达农场17
从农场1往东经距离7到达农场17
. . .
最近美国过度肥胖非常普遍。农夫约翰为了让他的奶牛多做运动,举办了奶牛马拉松。马拉松路线要尽量长。
奶牛们拒绝跑马拉松,因为她们悠闲的生活无法承受约翰选择的如此长的赛道。因此约翰决心找一条更合理的赛道。他打算咨询你。读入地图之后会有K个问题,每个问题包括2个整数,就是约翰感兴趣的2个农场的编号,请尽快算出这2个农场间的距离。
【输入格式】
第1行:两个分开的整数N和M。
第2到M+1行:每行包括4个分开的内容,F1,F2,L,D分别描述两个农场的编号,道路的长度,F1到F2的方向N,E,S,W。
第2+M行:一个整数K(1<=K<=10000).
第3+M到2+M+K行:每行输入2个整数,代表2个农场。
【输出格式】
对每个问题,输出单独的一个整数,给出正确的距离。
【样例输入】
7 6 1 6 13 E 6 3 9 E 3 5 7 S 4 1 3 N 2 4 20 W 4 7 2 S 3 1 6 1 4 2 6
【样例输出】
13 3 36
【提示】
农场2到农场6有20+3+13=36的距离。
【来源】
Brian Dean,2004
USACO 2004 February Contest Green Problem 3 Distance Queries
方向 没用
裸最短路 超时
用dis[i]记录i到根的距离,ans=dis[u]+dis[v]-2*dis[lca[u,v]] 画个图就能看出来了
模板题
1 #include <algorithm> 2 #include <iostream> 3 #include <cstdio> 4 #include <queue> 5 6 using namespace std; 7 8 const int N(40000+15); 9 int n,m,u,v,w,k; 10 char ch; 11 12 int head[N],sumedge,cnt; 13 struct Edge 14 { 15 int u,v,w,next; 16 Edge(int u=0,int v=0,int next=0,int w=0): 17 u(u),v(v),next(next),w(w){} 18 }edge[N<<1],e[N<<1]; 19 void Insert(int u,int v,int w) 20 { 21 edge[++sumedge]=Edge(u,v,head[u],w); 22 head[u]=sumedge; 23 } 24 25 int size[N],deep[N],top[N],dad[N],dis[N]; 26 void DFS(int x) 27 { 28 size[x]=1; deep[x]=deep[dad[x]]+1; 29 for(int i=head[x];i;i=edge[i].next) 30 { 31 int to=edge[i].v; 32 if(dad[x]==to) continue; 33 dad[to]=x;dis[to]+=dis[x]+edge[i].w;DFS(to);size[x]+=size[to]; 34 } 35 } 36 void DFS_(int x) 37 { 38 int t=0; if(!top[x]) top[x]=x; 39 for(int i=head[x];i;i=edge[i].next) 40 { 41 int to=edge[i].v; 42 if(dad[x]!=to&&size[t]<size[to]) t=to; 43 } 44 if(t) top[t]=top[x],DFS_(t); 45 for(int i=head[x];i;i=edge[i].next) 46 { 47 int to=edge[i].v; 48 if(dad[x]!=to&&to!=t) DFS_(to); 49 } 50 } 51 int LCA(int x,int y) 52 { 53 for(;top[x]!=top[y];x=dad[top[x]]) 54 if(deep[top[x]]<deep[top[y]]) swap(x,y); 55 return deep[x]<deep[y]?x:y; 56 } 57 58 int main() 59 { 60 freopen("dquery.in","r",stdin); 61 freopen("dquery.out","w",stdout); 62 63 scanf("%d%d",&n,&m); 64 for(;m;m--) 65 { 66 scanf("%d%d%d %c",&u,&v,&w,&ch); 67 e[++cnt].u=u;e[cnt].v=v;e[cnt].w=w; 68 Insert(u,v,w);Insert(v,u,w); 69 } 70 DFS(1);DFS_(1); 71 scanf("%d",&k); 72 for(;k;k--) 73 { 74 scanf("%d%d",&u,&v); 75 printf("%d\n",dis[u]+dis[v]-(dis[LCA(u,v)]<<1)); 76 } 77 return 0; 78 }