码迷,mamicode.com
首页 > 其他好文 > 详细

【洛谷p2245】星际导航

时间:2016-05-07 13:26:48      阅读:283      评论:0      收藏:0      [点我收藏+]

标签:

 终于写了一点干货,这题终于不是水题了

题目戳这里

题目大意就是给你一个图,然后找到两点之间所有路径中边权最大值最小的那一条,输出最小值。

一开始一看最大值最小就用二分答案弄了一遍,结果没看数据范围只有40分QAQ

然后正解是先构造一颗最小生成树,再在树上求lca

为什么呢?我是用反证法考虑的。假如由u到v存在一条路径的边权最大值最小,且这条边不在生成树上。【为了放便表示设max(u,v)表示u到v边权的最大值】设这条边连接的点为i,j,首先易知max(u,i)<a(i,j),max(j,v)<a(i,j),又因为最小生成树的性质我们可以知道在树上一定存在一条路径max(i,j)<a(i,j),即一定存在一条更优的路径,这与假设矛盾。

接下来就是写代码了。求lca我用的是tarjan,在树上找到lca之后我是直接求两点到lca的路径,时间非常差但是居然神奇的ac了……果然是数据太弱。同时由于数据太大要写三次邻接表,然后各种麻烦。其实这题思路找出来之后就很明了了,剩下的就是看码力了。具体做法看代码吧,我写的比较丑。

 

  1 program j01;
  2 type xx=record
  3           lx,rx,da:longint;
  4         end;
  5 var q,next,data,q1,next1,data1:array[1..400000]of longint;
  6     a:Array[1..400000]of xx;
  7     head,head1,f,d,fa,fad:array[1..100000]of longint;
  8     n,m,j,i,t,qq,x,y,tt:longint;
  9     ans:Array[1..100000]of longint;
 10     b:array[1..100000]of boolean;
 11 
 12 function max(a,b:longint):longint;
 13 begin
 14   if a>b then exit(a) else exit(b);
 15 end;
 16 
 17 function gff(i:longint):longint;//并查集
 18 var x:longint;
 19 begin
 20   if f[i]=i then exit(i);
 21   x:=gff(f[i]);
 22   f[i]:=x;
 23   exit(x);
 24 end;
 25 
 26 procedure mer(i,j:longint);//合并
 27 var x,y:longint;
 28 begin
 29   x:=gff(i);
 30   y:=gff(j);
 31   f[x]:=y;
 32 end;
 33 
 34 procedure add(a,b,c:longint);
 35 begin
 36   inc(tt);
 37   q[tt]:=b;
 38   next[tt]:=head[a];
 39   head[a]:=tt;
 40   data[tt]:=c;
 41 end;
 42 
 43 procedure add1(a,b,c:longint);
 44 begin
 45   inc(tt);
 46   q1[tt]:=b;
 47   next1[tt]:=head1[a];
 48   head1[a]:=tt;
 49   data1[tt]:=c;
 50 end;
 51 
 52 procedure qs(l,r:longint);
 53 var i,j,x:longint;
 54     y:xx;
 55 begin
 56   i:=l;
 57   j:=r;
 58   x:=a[(i+j)div 2].da;
 59   repeat
 60     while a[i].da<x do inc(i);
 61     while x<a[j].da do dec(j);
 62     if i<=j then
 63     begin
 64       y:=a[i];
 65       a[i]:=a[j];
 66       a[j]:=y;
 67       inc(i);
 68       dec(j);
 69     end;
 70   until i>j;
 71   if i<r then qs(i,r);
 72   if l<j then qs(l,j);
 73 end;
 74 
 75 procedure kruscal;//求最小生成树
 76 var i,j:longint;
 77 begin
 78   for i:=1 to n do f[i]:=i;
 79   fillchar(head,sizeof(head),0);
 80   i:=n-1;
 81   tt:=0;
 82   for j:=1 to m do
 83   begin
 84     if gff(a[j].lx)<>gff(a[j].rx)  then
 85     begin
 86     mer(a[j].lx,a[j].rx);
 87     add(a[j].lx,a[j].rx,a[j].da);
 88     add(a[j].rx,a[j].lx,a[j].da);
 89     dec(i);
 90     end;
 91     if i=0 then exit;
 92   end;
 93 end;
 94 
 95 procedure bbu(i,pre:longint);//构造最小生成树
 96 var j:longint;
 97 begin
 98   fa[i]:=pre;
 99   j:=head[i];
100   while j<>0 do
101   begin
102     if q[j]<>pre then
103     begin
104       add1(i,q[j],data[j]);
105       fad[q[j]]:=data[j];
106       bbu(q[j],i);
107     end;
108     j:=next[j];
109   end;
110 end;
111 
112 function ss(i,x:longint):longint;//求路径上最大值
113 begin
114   if i=x then exit(0);
115   ss:=max(fad[i],ss(fa[i],x));
116 end;
117 
118 procedure lca(i:longint);//最近公共祖先
119 var j,x:longint;
120 begin
121   j:=head1[i];
122   while j<>0 do
123   begin
124     lca(q1[j]);
125     mer(q1[j],i);
126     j:=next1[j];
127   end;
128   j:=head[i];
129   b[i]:=true;
130   while j<>0 do
131   begin
132     if b[q[j]] then
133     begin
134       x:=gff(q[j]);
135       ans[data[j]]:=max(ss(q[j],x),ss(i,x));
136     end;
137     j:=next[j];
138   end;
139 end;
140 
141 begin
142   readln(n,m);
143   for i:=1 to m do readln(a[i].lx,a[i].rx,a[i].da);
144   qs(1,m);
145   kruscal;
146   tt:=0;
147   fillchar(head1,sizeof(head1),0);
148   bbu(1,0);
149   fillchar(q,sizeof(q),0);
150   fillchar(head,sizeof(head),0);
151   fillchar(next,sizeof(next),0);
152   tt:=0;
153   readln(qq);
154   for i:=1 to qq do
155   begin
156     readln(x,y);
157     add(x,y,i);
158     add(y,x,i);
159   end;
160   fillchar(b,sizeof(b),false);
161   for i:=1 to n do f[i]:=i;
162   fillchar(d,sizeof(d),0);
163   t:=0;
164   lca(1);
165   for i:=1 to qq do if ans[i]=0 then writeln(impossible) else writeln(ans[i]);
166 end.

 

 

 

---恢复内容结束---

【洛谷p2245】星际导航

标签:

原文地址:http://www.cnblogs.com/oldjang/p/5467941.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!