【NOIP2013模拟】Freda的传呼机

Time Limits: 100 ms Memory Limits: 131072 KB

Description
为了 随时 与 rainbow快速交流, Freda制造了 两部传呼机 。Freda和 rainbow所在的地方有N座房屋、M条双向 光缆 。每条光缆连接两座房屋, 传呼机发出的信号只能沿着光缆传递,并且 传呼机的信号 从光缆的其中一端传递到另需要花费 t单位时间 。现在 Freda要 进行 Q次试验, 每次选取两座房屋,并想知道 传呼机的信号在这两座房屋之间传递 至少需 要多长时间。 Freda 和 rainbow简直弱爆了有木有T_TT_T ,请你帮他们吧……

N座房屋 通过光缆 一定是连通的, 并且这 M条光缆有以下三类连接情况:

A:光缆不形成环 ,也就是光缆仅 有 N-1条。
B:光缆只 形成一个环,也就是光缆 仅有 N条。
C:每条光缆仅在一个环中。

Input
第一行 包含三个用空格隔开的整数, N、M和 Q。
接下来 M行每三个整数 x、y、t,表示 房屋 x和 y之间有一条传递时为 t的光缆 。
最后 Q行每两个整数 x、y,表示 Freda想知道 在 x和 y之间传呼最少需要多长时间。

Output
输出 Q行,每一个整数表示 Freda每次试验的结果 。

Sample Input
Input1:
5 4 2
1 2 1
1 3 1
2 4 1
2 5 1
3 5
2 1

Input2:
5 5 2
1 2 1
2 1 1
1 3 1
2 4 1
2 5 1
3 5
2 1

Input3:
9 10 2
1 2 1
1 4 1
3 4 1
2 3 1
3 7 1
7 8 2
7 9 2
1 5 3
1 6 4
5 6 1
1 9
5 7

Sample Output
Output1:
3
1

Output2:
3
1

Output3:
5
6

Data Constraint

  • 送分数据占10%,2<=N<=1000,N-1<=M<=1200。
  • A类数据占30%,M=N-1。
  • B类数据占50%,M=N。
  • C类数据占10%,M>N。
  • 对于100%的数据,2<=N<=10000,N-1<=M<=12000,Q=10000,1<=x,y<=N,1<=t<=32768。

题目大意

给你一个图,图上每一条边最多只能在一个环中,给出Q组询问,每组询问是x,y,答x到y的最短距离


解题思路

业界毒瘤?仙人掌?不懂,总之讲一讲我的方法吧:
方法就是lca,可以将每个环看作一个节点,也就是说,除了环顶之外,其余环中的看作一点,那么我们就可以求出fa[x] (环顶或者父亲节点)和 di[x] (这个点到父亲节点的距离或到环顶的两条距离中,最小值)

  1. 我们可以首先用dfs找fa,di,标记光缆编号。
  2. 然后再一次dfs找出节点所在的层
  3. 最后lca一遍。

Codes

constmaxn=19231; maxx=83721;
var dis,s,p,first,last,f,owner,floor:array[0..10000]of longint;fa,di:array[0..10000,0..16]of longint;hush:array[0..maxn,1..3]of longint;n,m,i,x,y,t,q,tot,j,top,z:longint;a:array[0..24000,1..4]of longint;bz,pd:array[0..12000]of boolean;stack:array[0..10000,1..2]of longint;
function ha(x,y:longint):longint; //哈希求每条光缆的编号var z:longint;
beginz:=((x*maxx)+(y*y*2-1))mod maxn;while (hush[z,3]<>0)and((hush[z,1]<>x)or(hush[z,2]<>y)) do z:=z mod maxn+1;exit(z);
end;
procedure insert(w,x,y,z:longint); //插入边集数组
begina[w,1]:=x; a[w,2]:=y; a[w,3]:=z; a[w,4]:=w;if first[x]=0 then first[x]:=w else a[last[x],4]:=w;last[x]:=w;
end;
function turn(x:longint):longint;
beginif x>m then x:=x-m;exit(x);
end;
function min(p,q:longint):longint;
beginif p<q then exit(p) else exit(q);
end;
procedure build(x,v,n,last:longint);  //找环,做fa,divar o,y,t:longint;
beginif f[x]<>0 then   //找到一个环begininc(tot);dis[tot]:=v-stack[f[x],2];for o:=f[x]+1 to n-1 dobeginy:=stack[o,1];pd[y]:=true;s[y]:=stack[o,2]-stack[f[x],2];p[y]:=dis[tot]-s[y];fa[y,0]:=x; di[y,0]:=min(s[y],p[y]);owner[y]:=tot;  //一个点的归属环end;end elsebeginf[x]:=n;  //将每个节点存入栈中stack[n,1]:=x;stack[n,2]:=v;o:=first[x];while 1=1 dobegint:=turn(o);if bz[t] then  //判断该边是否走过beginif o=a[o,4] then break;o:=a[o,4];continue;end;y:=a[o,2];bz[t]:=true;build(y,v+a[o,3],n+1,x);if a[o,4]=o then break;o:=a[o,4];end;if not pd[x] then  //处理不是环的情况begininc(tot);owner[x]:=tot;fa[x,0]:=last;di[x,0]:=stack[n,2]-stack[n-1,2];end;end;
end;
procedure find(x,t:longint);  //求每个点的层数var o,y:longint;
begino:=first[x];floor[x]:=t;bz[x]:=true;while 1=1 dobeginy:=a[o,2];if bz[y] thenbeginif a[o,4]=o then break;o:=a[o,4];continue;end;if owner[y]<>owner[x] then find(y,t+1) else find(y,t);if a[o,4]=o then break;o:=a[o,4];end;
end;
function min(x,y,z:longint):longint;
beginif x>y then x:=y;if x>z then x:=z;exit(x);
end;
procedure swap(var a,b:longint);var c:longint;
beginc:=a; a:=b; b:=c;
end;
function ask(x,y:longint):longint;  //求两点的最短路径var dis,o:longint;
beginif floor[x]>floor[y] then swap(x,y);dis:=0;for o:=16 downto 0 doif 1<<o<=floor[y]-floor[x] thenbegininc(dis,di[y,o]);y:=fa[y,o];end;for o:=16 downto 0 dobeginif fa[x,o]<>fa[y,o] thenbegininc(dis,di[x,o]+di[y,o]);x:=fa[x,o]; y:=fa[y,o];end;end;if owner[x]=owner[y] then exit(dis+min(abs(s[x]-s[y]),s[x]+p[y],p[x]+s[y])) else exit(dis+di[x,0]+di[y,0]);
end;
beginassign(input,'pager.in'); reset(input);assign(output,'pager.out'); rewrite(output);read(n,m,q);for i:=1 to m dobeginread(x,y,z);if x>y then swap(x,y);t:=ha(x,y);if hush[t,3]<>0 then  //将两点之间的所有直接到达的路求最小值begint:=hush[t,3];a[t,3]:=min(a[t,3],z);a[t+m,3]:=min(a[t+m,3],z);end elsebegininc(top);hush[t,1]:=x; hush[t,2]:=y; hush[t,3]:=top;insert(top,x,y,z);insert(top+m,y,x,z);end;end;build(1,0,1,0);for j:=1 to 16 do  //搞lcafor i:=1 to n dobeginfa[i,j]:=fa[fa[i,j-1],j-1];di[i,j]:=di[i,j-1]+di[fa[i,j-1],j-1];end;fillchar(bz,sizeof(bz),false);find(1,1);for i:=1 to q dobeginread(x,y);writeln(ask(x,y));end;close(output); close(input);
end.

【NOIP2013模拟】Freda的传呼机相关推荐

  1. 【NOIP2013模拟】四叶草魔杖

    [NOIP2013模拟]四叶草魔杖 Time Limits: 1000 ms Memory Limits: 131072 KB Description 魔杖护法Freda融合了四件武器,于是魔杖顶端缓 ...

  2. JZOJ 3461. 【NOIP2013模拟联考5】小麦亩产一千八(kela)

    3461. [NOIP2013模拟联考5]小麦亩产一千八(kela) (Standard IO) Time Limits: 1000 ms  Memory Limits: 262144 KB  Det ...

  3. JZOJ 3518. 【NOIP2013模拟11.6A组】进化序列(evolve)

    3518. [NOIP2013模拟11.6A组]进化序列(evolve) (File IO): input:evolve.in output:evolve.out Time Limits: 1000 ...

  4. jzoj 3461. 【NOIP2013模拟联考5】小麦亩产一千八(math)

    3461. [NOIP2013模拟联考5]小麦亩产一千八 Description "有了金坷垃,肥料一袋能顶两袋撒,小麦亩产一千八,吸收两米下的氮磷钾--",话说HYSBZ(Hen ...

  5. JZOJ 3388. 【NOIP2013模拟】绿豆蛙的归宿

    3388. [NOIP2013模拟]绿豆蛙的归宿 (Standard IO) Time Limits: 1000 ms  Memory Limits: 131072 KB  Detailed Limi ...

  6. 【NOIP2013模拟】Freda的传呼机 题解+代码

    这题又有点像码农题!! Description 为了 随时 与 rainbow快速交流, Freda制造了 两部传呼机 .Freda和 rainbow所在的地方有N座房屋.M条双向 光缆 .每条光缆连 ...

  7. JZOJ3395. 【NOIP2013模拟】Freda的传呼机

    题目大意 给一个包含N个节点和M条双向边的图(保证每条边只会最多出现在一个环中,即仙人掌)和Q个询问. 输入x,y,t表示x,y之间有一条长度为t的双向边. 接下来Q个询问,每个询问(u,v)求(u, ...

  8. Acwing 360. Freda的传呼机(仙人掌图重构,lca)

    为了随时与rainbow快速交流,Freda制造了两部传呼机.Freda和rainbow所在的地方有N座房屋.M 条双向光缆. 每条光缆连接两座房屋,传呼机发出的信号只能沿着光缆传递,并且传呼机的信号 ...

  9. 「Nescafé26」 Freda的传呼机 【树上倍增+图论】

    题目: 为了随时与rainbow快速交流,Freda制造了两部传呼机.Freda和rainbow所在的地方有N座房屋.M条双向光缆.每条光缆连接两座房屋,传呼机发出的信号只能沿着光缆传递,并且传呼机的 ...

最新文章

  1. 怎样把centos 6.2 系统里的网卡em1还原为eth0
  2. c 文件怎么进行读取和写入操作?
  3. SH760二自由度系统解析法求全解-过渡及稳态过程
  4. MAC安装向日葵软件步骤
  5. 烧录superboot.bin 到 友善之臂mini2440 开发板
  6. VC “变速齿轮”再研究
  7. 【英语语法入门】 第22讲 完成时
  8. 【Go】Go语言中反射包的实现原理(The Laws of Reflection)
  9. linux中文成方块,给linux添加字体
  10. 海湾gst5000协议号_海湾GST5000控制器说明书(DEMO)预案.doc
  11. 清除keep-alive缓存,动态缓存
  12. android如何用真机测试,android studio如何使用真机测试app
  13. USB 传输方式(控制)
  14. HtmlUnit、Jsoup、webmagic基本介绍
  15. 计算机公司经营范围安防监控,监控安防在个体经营范围怎么写?
  16. 一些写英文简历的词汇
  17. 手机sd卡中的图片误删?Mac数码相机中的照片丢失?
  18. Linux aarch64交叉编译之 assimp模型库
  19. 何隆昌 帆软报表汇总,相减,注意事项
  20. 微信小程序加密消息解密工具类

热门文章

  1. Elasticsearch:ingest pipeline 使用示例 - 解析常用日志格式
  2. 微信公共平台 “token验证失败”的一个原因
  3. 【工具篇】Joystick Pack摇杆使用Unity多场景使用摇杆
  4. 在腾讯实习一年,我学到了什么
  5. HTML 文本格式化
  6. 输入字符串 "I am a student",则输出 "student.a am I " 。
  7. 前端基础(13):CSS3新增属性和选择器
  8. 电路图:MC34063 2.2V-6V升压到7V电路
  9. 【vue-清除默认样式-完结】
  10. 符号速率,码片速率,业务速率,信道编码,扩频因子