Description
一天,Y 君在测量体重的时候惊讶的发现,由于常年坐在电脑前认真学习,她的体重有了突 飞猛进的增长。
幸好 Y 君现在退役了,她有大量的时间来做运动,她决定每天从教学楼跑到食堂来减肥。
Y 君将学校中的所有地点编号为 1 到 n,其中她的教学楼被编号为 S,她的食堂被编号为 T, 学校中有 m 条连接两个点的双向道路,保证从任意一个点可以通过道路到达学校中的所有点。
然而 Y 君不得不面临一个严峻的问题,就是天气十分炎热,如果 Y 君太热了,她就会中暑。 于是 Y 君调查了学校中每条路的温度 t,及通过一条路所需的时间 c。Y 君在温度为 t 的地 方跑单位时间,就会使她的热量增加 t。
由于热量过高 Y 君就会中暑,而且 Y 君也希望在温度较低的路上跑,她希望在经过的所有 道路中最高温度最低的前提下,使她到达食堂时的热量最低 (从教学楼出发时,Y 君的热量为 0)。
请你帮助 Y 君设计从教学楼到食堂的路线,以满足她的要求。你只需输出你设计的路线中所 有道路的最高温度和 Y 君到达食堂时的热量。
幸好 Y 君现在退役了,她有大量的时间来做运动,她决定每天从教学楼跑到食堂来减肥。
Y 君将学校中的所有地点编号为 1 到 n,其中她的教学楼被编号为 S,她的食堂被编号为 T, 学校中有 m 条连接两个点的双向道路,保证从任意一个点可以通过道路到达学校中的所有点。
然而 Y 君不得不面临一个严峻的问题,就是天气十分炎热,如果 Y 君太热了,她就会中暑。 于是 Y 君调查了学校中每条路的温度 t,及通过一条路所需的时间 c。Y 君在温度为 t 的地 方跑单位时间,就会使她的热量增加 t。
由于热量过高 Y 君就会中暑,而且 Y 君也希望在温度较低的路上跑,她希望在经过的所有 道路中最高温度最低的前提下,使她到达食堂时的热量最低 (从教学楼出发时,Y 君的热量为 0)。
请你帮助 Y 君设计从教学楼到食堂的路线,以满足她的要求。你只需输出你设计的路线中所 有道路的最高温度和 Y 君到达食堂时的热量。
Input
第一行由一个空格隔开的两个正整数 n, m,代表学校中的地点数和道路数。
接下来 m 行,每行由一个空格隔开的四个整数 a, b, t, c 分别代表双向道路的两个端点,温度 和通过所需时间.
最后一行由一个空格隔开的两个正整数 S, T,代表教学楼和食堂的编号。
注意:输入数据量巨大,请使用快速的读入方式。
接下来 m 行,每行由一个空格隔开的四个整数 a, b, t, c 分别代表双向道路的两个端点,温度 和通过所需时间.
最后一行由一个空格隔开的两个正整数 S, T,代表教学楼和食堂的编号。
注意:输入数据量巨大,请使用快速的读入方式。
Output
一行由一个空格隔开的两个整数,分别代表最高温度和热量。
Solution
考虑将所有边按温度从小到大排序加入图中,同时用并查集维护 S 和 T 的连通性。
如果加入某些边之后 S 和 T 联通了,那么跑一遍 S 到 T 的最短路即可得到答案。
注意温度相等的边要一起加入图中。 时间复杂度 O(m log m)。
代码
1 type 2 arr=record 3 x,y,next:longint; 4 w:int64; 5 end; 6 var 7 n,m,nm,q,z,maxt:longint; 8 a:array [0..2000001] of arr; 9 x,y,t,c:array [0..1000001] of longint; 10 fa,ls,list,v:array [0..500001] of longint; 11 d:array [0..500001] of int64; 12 procedure init; 13 var 14 i:longint; 15 begin 16 readln(n,m); 17 for i:=1 to m do 18 readln(x[i],y[i],t[i],c[i]); 19 readln(q,z); 20 end; 21 22 procedure qsort(l,r:longint); 23 var 24 mid,i,j,k:longint; 25 begin 26 if l>r then exit; 27 i:=l; j:=r; 28 mid:=t[(l+r) div 2]; 29 repeat 30 while t[i]<mid do inc(i); 31 while t[j]>mid do dec(j); 32 if i<=j then 33 begin 34 k:=x[i]; x[i]:=x[j]; x[j]:=k; 35 k:=y[i]; y[i]:=y[j]; y[j]:=k; 36 k:=t[i]; t[i]:=t[j]; t[j]:=k; 37 k:=c[i]; c[i]:=c[j]; c[j]:=k; 38 inc(i); dec(j); 39 end; 40 until i>j; 41 qsort(i,r); 42 qsort(l,j); 43 end; 44 45 procedure add(xx,yy,zz:longint); 46 begin 47 inc(nm); 48 a[nm].x:=xx; a[nm].y:=yy; a[nm].w:=zz; 49 a[nm].next:=ls[xx]; ls[xx]:=nm; 50 end; 51 52 function get(x:longint):longint; 53 begin 54 if (fa[x]=0) or (fa[x]=x) then exit(x); 55 fa[x]:=get(fa[x]); 56 exit(fa[x]); 57 end; 58 59 function max(o,p:longint):longint; 60 begin 61 if o>p then exit(o); 62 exit(p); 63 end; 64 65 procedure main; 66 var 67 i,tt,kk:longint; 68 begin 69 fillchar(fa,sizeof(fa),0); 70 nm:=0; i:=1; maxt:=0; 71 while i<=m do 72 begin 73 maxt:=max(maxt,t[i]); 74 while t[i]=t[i+1] do 75 begin 76 add(x[i],y[i],t[i]*c[i]); 77 add(y[i],x[i],t[i]*c[i]); 78 tt:=get(x[i]); kk:=get(y[i]); 79 fa[tt]:=kk; 80 inc(i); 81 end; 82 add(x[i],y[i],t[i]*c[i]); 83 add(y[i],x[i],t[i]*c[i]); 84 tt:=get(x[i]); kk:=get(y[i]); 85 fa[tt]:=kk; 86 if get(q)=get(z) then break; 87 inc(i); 88 end; 89 end; 90 91 procedure spfa(xx:longint); 92 var 93 head,tail,i:longint; 94 begin 95 for i:=0 to 500001 do 96 d[i]:=10000000000000000; 97 head:=0; tail:=1; 98 d[xx]:=0; v[xx]:=1; list[1]:=xx; 99 repeat 100 inc(head); 101 i:=ls[list[head]]; 102 while i<>0 do 103 begin 104 if d[a[i].x]+a[i].w<d[a[i].y] then 105 begin 106 d[a[i].y]:=d[a[i].x]+a[i].w; 107 if v[a[i].y]=0 then 108 begin 109 v[a[i].y]:=1; 110 inc(tail); 111 list[tail]:=a[i].y; 112 end; 113 end; 114 i:=a[i].next; 115 end; 116 v[list[head]]:=0; 117 until head>tail; 118 end; 119 120 begin 121 assign(input,'running.in'); 122 assign(output,'running.out'); 123 reset(input); 124 rewrite(output); 125 init; 126 qsort(1,m); 127 main; 128 spfa(q); 129 writeln(maxt,' ',d[z]); 130 close(input); 131 close(output); 132 end.