3732: Network

3732: Network

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 395  Solved: 179
[Submit][Status]

Description

给你N个点的无向图 (1 <= N <= 15,000),记为:1…N。 
图中有M条边 (1 <= M <= 30,000) ,第j条边的长度为: d_j ( 1 < = d_j < = 1,000,000,000).

现在有 K个询问 (1 < = K < = 15,000)。 
每个询问的格式是:A B,表示询问从A点走到B点的所有路径中,最长的边最小值是多少?

Input

第一行: N, M, K。 
第2..M+1行: 三个正整数:X, Y, and D (1 <= X <=N; 1 <= Y <= N). 表示X与Y之间有一条长度为D的边。 
第M+2..M+K+1行: 每行两个整数A B,表示询问从A点走到B点的所有路径中,最长的边最小值是多少?

Output

对每个询问,输出最长的边最小值是多少。

Sample Input

6 6 8
1 2 5
2 3 4
3 4 3
1 4 8
2 5 7
4 6 2
1 2
1 3
1 4
2 3
2 4
5 1
6 2
6 1

Sample Output

5
5
5
4
4
7
4
5

HINT

1 <= N <= 15,000

1 <= M <= 30,000

1 <= d_j <= 1,000,000,000

1 <= K <= 15,000

Source

题解:简直逗比到家啊——昨天我的程序先是TLE,但是一想这个复杂度应该不会啊,感觉不对头,于是发现了数组开小了(phile:数组开小怎么会TLE? HansBug:我哪知道= =)然后再交就WA,不停的WA,我硬是找了一个晚上的错,结果啥都没弄出来,还是那样,弃疗了,向lydsy2012要了下数据。。。今天数据到手,手工一测试,怎么测都没错?!?!然后再Submit一次一个字都没动的程序,Accept(HansBug:这。。。)。。。好了说思路——这题可以算是NOIP2013货车运输的修改+略微强化版,先是求出最小生成树(额。。我一般用并查集写prim),然后DFS建树,然后用倍增进行O(nlogn)的初始化,然后每次一个O(logn)地求LCA(至于路径上的最大值嘛,只要再加一个数组就行啦),就这样O(nlogn)地AC之。。。(HansBug:不过这个逗比的Judge还是害得我纠结了一晚上啊TT phile:不是和你说了嘛变量不清零有时候会跪掉。。。 HansBug:GET IT。。。)

  1 type
  2     point=^node;
  3     node=record
  4                w,g:longint;
  5                next:point;
  6     end;
  7
  8 var
  9    i,j,k,l,m,n,t:longint;
 10    a:array[0..40000] of point;
 11    b:array[0..40000,1..3] of longint;
 12    c,f,g,h:array[0..40000] of longint;
 13    d:array[0..20,0..40000] of longint;
 14    e:array[0..20,0..40000] of longint;
 15 function getfat(x:longint):longint;inline;
 16          begin
 17               while x<>c[x] do x:=c[x];
 18               getfat:=x;
 19          end;
 20 function tog(x,y:longint):boolean;inline;
 21          begin
 22               exit(getfat(x)=getfat(y));
 23          end;
 24 procedure merge(x,y:longint);inline;
 25           begin
 26                c[getfat(x)]:=getfat(y);
 27           end;
 28
 29 procedure add(x,y,z:longint);inline;
 30           var p:point;
 31           begin
 32                new(p);
 33                p^.g:=y;
 34                p^.w:=z;
 35                p^.next:=a[x];
 36                a[x]:=p;
 37           end;
 38 procedure swap(var x,y:longint);inline;
 39           var z:longint;
 40           begin
 41                z:=x;x:=y;y:=z;
 42           end;
 43 procedure sort(l,r:longint);inline;
 44           var i,j,x,y:longint;
 45           begin
 46                i:=l;j:=r;x:=b[(l+r) div 2,3];
 47                repeat
 48                      while b[i,3]<x do inc(i);
 49                      while b[j,3]>x do dec(j);
 50                      if i<=j then
 51                         begin
 52                              swap(b[i,1],b[j,1]);
 53                              swap(b[i,2],b[j,2]);
 54                              swap(b[i,3],b[j,3]);
 55                              inc(i);dec(j);
 56                         end;
 57                until i>j;
 58                if l<j then sort(l,j);
 59                if i<r then sort(i,r);
 60           end;
 61 procedure dfs(x:longint);inline;
 62           var p:point;
 63           begin
 64                p:=a[x];
 65                while p<>nil do
 66                      begin
 67                           if d[0,p^.g]=0 then
 68                              begin
 69                                   d[0,p^.g]:=x;
 70                                   e[0,p^.g]:=p^.w;
 71                                   c[p^.g]:=c[x]+1;
 72                                   dfs(p^.g);
 73                              end;
 74                           p:=p^.next;
 75                      end;
 76           end;
 77 function max(x,y:longint):longint;inline;
 78          begin
 79               if x>y then max:=x else max:=y;
 80          end;
 81 function fatget(x,y:longint):longint;//inline;
 82          var i:longint;
 83          begin
 84               i:=0;
 85               while y>0 do
 86                     begin
 87                          if odd(y) then x:=d[i,x];
 88                          inc(i);
 89                          y:=y div 2;
 90                     end;
 91               exit(x);
 92          end;
 93 function getmax(x,y:longint):longint;//inline;
 94          var i,j:longint;
 95          begin
 96               i:=0;j:=0;
 97               while y>0 do
 98                     begin
 99                          if odd(y) then
100                             begin
101                                  j:=max(j,e[i,x]);
102                                  x:=d[i,x];
103                             end;
104                          inc(i);
105                          y:=y div 2;
106                     end;
107               exit(j);
108          end;
109 function getcom(x,y:longint):longint;//inline;
110          var i,j,k,l:longint;
111          begin
112               if x=y then exit(x);
113               if c[x]<c[y] then swap(x,y);
114               x:=fatget(x,c[x]-c[y]);
115               if x=y then exit(x);
116               i:=20;
117               while i>=0 do
118                     begin
119                          if d[i,x]<>d[i,y] then
120                             begin
121                                  x:=d[i,x];
122                                  y:=d[i,y];
123                             end;
124                          dec(i);
125                     end;
126               exit(d[0,x]);
127          end;
128 function getpath(x,y:longint):longint;//inline;
129          var i,j,k,l:longint;
130          begin
131               l:=getcom(x,y);
132               getpath:=max(getmax(x,c[x]-c[l]),getmax(y,c[y]-c[l]));
133          end;
134
135 begin
136      readln(n,m,t);
137      for i:=1 to n do a[i]:=nil;
138      for i:=1 to n do c[i]:=i;
139      for i:=1 to m do
140          readln(b[i,1],b[i,2],b[i,3]);
141      sort(1,m);
142      j:=1;
143      for i:=1 to n-1 do
144          begin
145               while tog(b[j,1],b[j,2]) do inc(j);
146               add(b[j,1],b[j,2],b[j,3]);
147               add(b[j,2],b[j,1],b[j,3]);
148               merge(b[j,1],b[j,2]);
149          end;
150      fillchar(d,sizeof(d),0);
151      fillchar(c,sizeof(c),0);
152      d[0,1]:=-1;
153      dfs(1);
154      d[0,1]:=0;
155      for i:=1 to 20 do
156          begin
157               for j:=1 to n do
158                   begin
159                        d[i,j]:=d[i-1,d[i-1,j]];
160                        e[i,j]:=max(e[i-1,d[i-1,j]],e[i-1,j]);
161                   end;
162          end;
163      for i:=1 to t do
164          begin
165               readln(j,k);
166               writeln(getpath(j,k));
167          end;
168 end.
169               
时间: 2024-10-15 06:02:10

3732: Network的相关文章

bzoj 3732: Network 树上两点边权最值

http://www.lydsy.com/JudgeOnline/problem.php?id=3732 首先想到,要使得最长边最短,应该尽量走最短的边,在MST上. 然后像LCA那样倍增娶个最大值 #include <bits/stdc++.h> #define IOS ios::sync_with_stdio(false) using namespace std; #define inf (0x3f3f3f3f) typedef long long int LL; const int ma

BZOJ 3732 Network

2016.1.28 纪念我BZOJ第一题 Description 给你N个点的无向图 (1 <= N <= 15,000),记为:1…N. 图中有M条边 (1 <= M <= 30,000) ,第j条边的长度为: d_j ( 1 < = d_j < = 1,000,000,000). 现在有 K个询问 (1 < = K < = 15,000). 每个询问的格式是:A B,表示询问从A点走到B点的所有路径中,最长的边最小值是多少? Input 第一行: N,

BZOJ 3732 Network Kruskal+倍增LCA

题目大意:给定一个n个点m条边的无向连通图,k次询问两点之间所有路径中最长边的最小值 NOIP2013 货车运输,几乎就是原题...只不过最小边最大改成了最大边最小... 首先看到最大值最小第一反应二分答案 但是二分答案O(kmlogn)明显做不了 这里我们考虑最小生成树 先生成一棵最小生成树,然后每次询问利用倍增LCA求出路径上的最大权值即可 本蒟蒻居然把LCA写挂了... 而且样例还过了... 伤不起啊... 90%达成 剩下一道刷点啥呢... #include<cstdio> #incl

BZOJ 3732 Network Link-Cut-Tree (我是认真的!!

题目大意:给定一个n个点m条边的无向连通图.k次询问两点之间全部路径中最长边的最小值 LCT的裸题! 首先维护一个动态的最小生成树,然后每次增加边时删除两点间路径上权值最大的边.最后询问时直接求x到y链上的最大权值就可以.水爆了! ! . .. 好吧开玩笑的 真正的题解见http://blog.csdn.net/popoqqq/article/details/39755703 我仅仅是闲得无聊水一发LCT罢了0.0 TLE了好久... 由于有边权为0的边我没更新... #include<cstd

BZOJ 3732 Network Kruskal重构树

题目大意:给定一个n个点m条边的无向连通图,k次询问两点之间所有路径中最长边的最小值 Kruskal+倍增LCA做法见http://blog.csdn.net/popoqqq/article/details/39755703 LCT做法见http://blog.csdn.net/popoqqq/article/details/39929277 Kruskal重构树真是强大--一不小心手滑就RANK1啥的-- 每加入一条边时,我们并不链接这条边的两端点,而是把这条边两端点所在并查集的根连接起来,而

BZOJ 3732 Network 最小瓶颈路

题目大意:给出一个无向边,很多询问,问x,y两地之间的最长路最短是多少. 思路:乍一看好像是二分啊.的确这个题二分可以做,但是时间会慢很多,有的题直接就T掉(NOIP2013货车运输).其实这个题的模型就是最小瓶颈路模型.解法就是把无向图变成一个最小生成树,然后两点之间的最长路就是满足题意的答案. CODE: #include <cstdio> #include <cstring> #include <iostream> #include <algorithm&g

bzoj3732: Network(最小生成树+LCA)

3732: Network 题目:传送门 题解: 第一眼就看到最大边最小,直接一波最小生成树. 一开始还担心会错,问了一波肉大佬,任意两点在最小生成树上的路径最大边一定是最小的. 那么事情就变得简单起来了嘿嘿嘿,建棵树,直接在线LCA啊,用一个mx[i][j]记录i往上2^j这段区间的最大值. 代码: 1 #include<cstdio> 2 #include<cstring> 3 #include<cstdlib> 4 #include<cmath> 5

bzoj 1000+AC

1500 [NOI2005]维修数列   5333 16036 1010 [HNOI2008]玩具装箱toy   5205 12140 2049 [Sdoi2008]Cave 洞穴勘测   4992 10282 1008 [HNOI2008]越狱   4820 11120 1503 [NOI2004]郁闷的出纳员   4629 12915 1208 [HNOI2004]宠物收养所   4216 10462 1026 [SCOI2009]windy数   4169 9168 1003 [ZJOI2

【BZOJ 3732】 Network Kruskal重构树+倍增LCA

Kruskal重构树裸题, Sunshine互测的A题就是Kruskal重构树,我通过互测了解到了这个神奇的东西... 理解起来应该没什么难度吧,但是我的Peaks连WA,,, 省选估计要滚粗了TwT #include<cstdio> #include<cstring> #include<algorithm> #define for1(i,a,n) for(int i=(a);i<=(n);i++) #define for2(i,a,n) for(int i=(a