首页 > 代码库 > NOI2014 魔法森林

NOI2014 魔法森林

3669: [Noi2014]魔法森林

Time Limit: 30 Sec  Memory Limit: 512 MB
Submit: 106  Solved: 62
[Submit][Status]

Description

为了得到书法大家的真传,小E同学下定决心去拜访住在魔法森林中的隐士。魔法森林可以被看成一个包含个N节点M条边的无向图,节点标号为1..N,边标号为1..M。初始时小E同学在号节点1,隐士则住在号节点N。小E需要通过这一片魔法森林,才能够拜访到隐士。

魔法森林中居住了一些妖怪。每当有人经过一条边的时候,这条边上的妖怪就会对其发起攻击。幸运的是,在号节点住着两种守护精灵:A型守护精灵与B型守护精灵。小E可以借助它们的力量,达到自己的目的。

只要小E带上足够多的守护精灵,妖怪们就不会发起攻击了。具体来说,无向图中的每一条边Ei包含两个权值Ai与Bi。若身上携带的A型守护精灵个数不少于Ai,且B型守护精灵个数不少于Bi,这条边上的妖怪就不会对通过这条边的人发起攻击。当且仅当通过这片魔法森林的过程中没有任意一条边的妖怪向小E发起攻击,他才能成功找到隐士。

由于携带守护精灵是一件非常麻烦的事,小E想要知道,要能够成功拜访到隐士,最少需要携带守护精灵的总个数。守护精灵的总个数为A型守护精灵的个数与B型守护精灵的个数之和。

Input

第1行包含两个整数N,M,表示无向图共有N个节点,M条边。 接下来M行,第行包含4个正整数Xi,Yi,Ai,Bi,描述第i条无向边。其中Xi与Yi为该边两个端点的标号,Ai与Bi的含义如题所述。 注意数据中可能包含重边与自环。

Output

输出一行一个整数:如果小E可以成功拜访到隐士,输出小E最少需要携带的守护精灵的总个数;如果无论如何小E都无法拜访到隐士,输出“-1”(不含引号)。

Sample Input

【输入样例1】
4 5
1 2 19 1
2 3 8 12
2 4 12 15
1 3 17 8
3 4 1 17
【输入样例2】
3 1
1 2 1 1

Sample Output

【输出样例1】

32
【样例说明1】
如果小E走路径1→2→4,需要携带19+15=34个守护精灵;
如果小E走路径1→3→4,需要携带17+17=34个守护精灵;
如果小E走路径1→2→3→4,需要携带19+17=36个守护精灵;
如果小E走路径1→3→2→4,需要携带17+15=32个守护精灵。
综上所述,小E最少需要携带32个守护精灵。
【输出样例2】
-1
【样例说明2】
小E无法从1号节点到达3号节点,故输出-1。

HINT

2<=n<=50,000

0<=m<=100,000

1<=ai ,bi<=50,000

Source

题解:

卡时真是一件痛苦的事儿。。考场上肯定卡不出来。。。

考场上怎么就sb的去枚举a,二分b,在spfa呢?更直观的想法不就是枚举a做mst吗?脑袋短路了。。。

正解是LCT,蒟蒻不会,先spfa水过。。

枚举a,做spfa即可,但这样只有30分,考虑各种优化:

1.每次枚举的时候 d 数组不用清空,如果 d[n]值发生了变化,一定走了一条当前枚举的 a 的上限,则每次用 d [n]+xx 来更新答案,如果没发生变化,也不会影响答案,因为xx是递增的

2.如果这样直接做的话会是答案错误,这是为什么?

  这是因为在加入了一条新边之后,不一定能更新从 1 出发的点,所以其他点就不会被加入队列,这条边就没用被用到!

  所以我们应当在枚举到一条边的时候,将这条边的两端打标记,spfa从这些有标记的点出发即可

3.发现TLE。。。

   如果打印出ans的变化值可以发现,在开始很长时间内ans都是 inf,也就是说 1 与 n 都不连通

   这样我们可以从小到大加入边,用并查集维护连通性,直到 1 与 n 第一次连通时,我们开始做 spfa,这样可以省掉一些无用的过程

综合以上3点,终于AC。。。

代码:

1.考场35分(真是RP啊。。。)

  1 const inf=maxlongint>>2;maxn=100000+10;  2 type node=record  3      from,go,next,v1,v2:longint;  4      end;  5 var a,b,d1,d2,head,fa:array[0..maxn] of longint;  6     q:array[0..10*maxn] of longint;  7     e:array[0..maxn*2] of node;  8     v:array[0..maxn] of boolean;  9     i,j,xx,yy,ll,tot,rr,x,y,point,mid:longint; 10     ans,n,m:int64; 11     function find(x:longint):longint; 12      begin 13      if fa[x]<>x then fa[x]:=find(fa[x]); 14      exit(fa[x]); 15      end; 16     function max(x,y:longint):longint; 17      begin 18      if x>y then exit(x) else exit(y); 19      end; 20 procedure sort1(l,r:longint); 21  var i,j,x,y:longint; 22  begin 23  i:=l;j:=r;x:=a[(i+j)>>1]; 24  repeat 25   while a[i]>x do inc(i); 26   while a[j]<x do dec(j); 27   if i<=j then 28    begin 29    y:=a[i];a[i]:=a[j];a[j]:=y; 30    inc(i);dec(j); 31    end; 32  until i>j; 33  if i<r then sort1(i,r); 34  if j>l then sort1(l,j); 35  end; 36 procedure sort2(l,r:longint); 37  var i,j,x,y:longint; 38  begin 39  i:=l;j:=r;x:=b[(i+j)>>1]; 40  repeat 41   while b[i]<x do inc(i); 42   while b[j]>x do dec(j); 43   if i<=j then 44    begin 45    y:=b[i];b[i]:=b[j];b[j]:=y; 46    inc(i);dec(j); 47    end; 48  until i>j; 49  if i<r then sort2(i,r); 50  if j>l then sort2(l,j); 51  end; 52 procedure insert(x,y,z,w:longint); 53  begin 54  inc(tot); 55  with e[tot] do 56   begin 57   from:=x;go:=y;next:=head[x];head[x]:=tot;v1:=z;v2:=w; 58   end; 59  end; 60 procedure spfa; 61  var i,x,y,h,t,tmp1,tmp2:longint; 62  begin 63  for i:=1 to n do d1[i]:=inf; 64  for i:=1 to n do d2[i]:=inf; 65  fillchar(v,sizeof(v),false); 66  h:=0;t:=1;q[1]:=1;d1[1]:=0;d2[1]:=0; 67  while h<t do 68   begin 69   inc(h); 70   x:=q[h];v[x]:=false; 71   i:=head[x]; 72   while i<>0 do 73    begin 74    y:=e[i].go; 75    tmp1:=max(d1[x],e[i].v1); 76    tmp2:=max(d2[x],e[i].v2); 77    if (tmp1<=xx) and (tmp2<=yy) and (tmp2<d2[y]) then 78     begin 79     d1[y]:=tmp1;d2[y]:=tmp2; 80     if not(v[y]) then 81      begin 82      v[y]:=true; 83      inc(t);q[t]:=y; 84      end; 85     end; 86    i:=e[i].next; 87    end; 88   end; 89  end; 90 procedure init; 91  begin 92  readln(n,m); 93  for i:=1 to n do fa[i]:=i; 94  for i:=1 to m do 95   begin 96   readln(x,y,a[i],b[i]); 97   xx:=find(x);yy:=find(y); 98   if xx<>yy then fa[xx]:=yy; 99   insert(x,y,a[i],b[i]);insert(y,x,a[i],b[i]);100   end;101  sort1(1,m);102  sort2(1,m);103  end;104 procedure work1;105  begin106  xx:=a[1];point:=1;107  while true do108   begin109   ll:=1;rr:=m;110   while ll<rr do111    begin112    mid:=(ll+rr)>>1;113    yy:=b[mid];114    spfa;115    if d2[n]<>inf then rr:=mid else ll:=mid+1;116    end;117   inc(point);118   while (point<=m) and (d1[n]<a[point]) do inc(point);119   if point>m then break;120   xx:=a[point];121   if d1[n]+d2[n]<ans then ans:=d1[n]+d2[n];122   end;123  writeln(ans);124  end;125 procedure work2;126  begin127  for i:=1 to 100 do128   begin129    xx:=random(a[1])+1;130    yy:=random(b[m])+1;131    spfa;132    if d1[n]+d2[n]<ans then ans:=d1[n]+d2[n];133   end;134  writeln(ans);135  end;136 begin137  assign(input,forest.in);assign(output,forest.out);138  reset(input);rewrite(output);139  init;140  ans:=inf;141  if find(1)<>find(n) then writeln(-1) else if n*m*16<50000000 then work1 else work2;142  close(input);close(output);143 end.   
View Code

2.朴素SPFA55分

  1 const inf=maxlongint>>2;maxn=100000+10;  2 type node=record  3      from,go,next,v1,v2:longint;  4      end;  5 var a,b,d1,d2,head,fa:array[0..maxn] of longint;  6     q:array[0..10*maxn] of longint;  7     e:array[0..maxn*2] of node;  8     v:array[0..maxn] of boolean;  9     i,j,xx,yy,l,tot,r,x,y:longint; 10     ans,n,m:int64; 11     function find(x:longint):longint; 12      begin 13      if fa[x]<>x then fa[x]:=find(fa[x]); 14      exit(fa[x]); 15      end; 16     function max(x,y:longint):longint; 17      begin 18      if x>y then exit(x) else exit(y); 19      end; 20     function min(x,y:longint):longint; 21      begin 22      if x<y then exit(x) else exit(y); 23      end; 24  25 procedure sort(l,r:longint); 26  var i,j,x,y:longint; 27  begin 28  i:=l;j:=r;x:=a[(i+j)>>1]; 29  repeat 30   while a[i]<x do inc(i); 31   while a[j]>x do dec(j); 32   if i<=j then 33    begin 34    y:=a[i];a[i]:=a[j];a[j]:=y; 35    inc(i);dec(j); 36    end; 37  until i>j; 38  if i<r then sort(i,r); 39  if j>l then sort(l,j); 40  end; 41 procedure insert(x,y,z,w:longint); 42  begin 43  inc(tot); 44  with e[tot] do 45   begin 46   from:=x;go:=y;next:=head[x];head[x]:=tot;v1:=z;v2:=w; 47   end; 48  end; 49 procedure spfa; 50  var i,x,y,h,t,tmp1,tmp2:longint; 51  begin 52  for i:=1 to n do d1[i]:=inf; 53  for i:=1 to n do d2[i]:=inf; 54  fillchar(v,sizeof(v),false); 55  h:=0;t:=1;q[1]:=1;d1[1]:=0;d2[1]:=0; 56  while h<t do 57   begin 58   inc(h); 59   x:=q[h];v[x]:=false; 60   i:=head[x]; 61   while i<>0 do 62    begin 63    y:=e[i].go; 64    tmp1:=max(d1[x],e[i].v1); 65    tmp2:=max(d2[x],e[i].v2); 66    if (tmp1<=xx) and (tmp2<d2[y]) then 67     begin 68     d1[y]:=tmp1;d2[y]:=tmp2; 69     if not(v[y]) then 70      begin 71      v[y]:=true; 72      inc(t);q[t]:=y; 73      end; 74     end; 75    i:=e[i].next; 76    end; 77   end; 78  end; 79 procedure init; 80  begin 81  readln(n,m); 82  for i:=1 to n do fa[i]:=i; 83  for i:=1 to m do 84   begin 85   readln(x,y,a[i],b[i]); 86   xx:=find(x);yy:=find(y); 87   if xx<>yy then fa[xx]:=yy; 88   insert(x,y,a[i],b[i]);insert(y,x,a[i],b[i]); 89   end; 90  sort(1,m); 91  end; 92 procedure work1; 93  begin 94  xx:=a[1];l:=0;r:=m; 95  while true do 96   begin 97   while a[l]=a[l-1] do inc(l); 98   inc(l);xx:=a[l]; 99   if l>r then break;100   spfa;101   while d1[n]+d2[n]<=a[r] do dec(r);102   ans:=min(ans,d1[n]+d2[n]);103   xx:=a[r];104   spfa;105   ans:=min(ans,d1[n]+d2[n]);106   while d1[n]<=a[r] do dec(r);107   end;108  writeln(ans);109  end;110 begin111  assign(input,forest.in);assign(output,forest.out);112  reset(input);rewrite(output);113  init;114  ans:=inf;115  if find(1)<>find(n) then writeln(-1) else work1;116  close(input);close(output);117 end.      
View Code

3.MST40分

  1 const inf=maxlongint>>2;maxn=100000+10;  2 type node=record  3      from,go,next,v1,v2:longint;  4      end;  5      arr=array[0..maxn] of longint;  6 var a,b,c,d,head,fa,aa:arr;  7     e:array[0..maxn*2] of node;  8     v,hash:array[0..maxn] of boolean;  9     i,j,xx,yy,l,tot,r,x,y,cnt:longint; 10     ans,n,m:int64; 11     flag:boolean; 12     function find(x:longint):longint; 13      begin 14      if fa[x]<>x then fa[x]:=find(fa[x]); 15      exit(fa[x]); 16      end; 17     function max(x,y:longint):longint; 18      begin 19      if x>y then exit(x) else exit(y); 20      end; 21     function min(x,y:longint):longint; 22      begin 23      if x<y then exit(x) else exit(y); 24      end; 25 procedure swap(var x,y:longint); 26  var t:longint; 27  begin 28  t:=x;x:=y;y:=t; 29  end; 30  31 procedure sort(l,r:longint); 32  var i,j,x:longint; 33  begin 34  i:=l;j:=r;x:=aa[(i+j)>>1]; 35  repeat 36   while aa[i]<x do inc(i); 37   while aa[j]>x do dec(j); 38   if i<=j then 39    begin 40    swap(aa[i],aa[j]); 41    inc(i);dec(j); 42    end; 43  until i>j; 44  if i<r then sort(i,r); 45  if j>l then sort(l,j); 46  end; 47 procedure sort1(l,r:longint); 48  var i,j,x:longint; 49  begin 50  i:=l;j:=r;x:=b[(i+j)>>1]; 51  repeat 52   while b[i]<x do inc(i); 53   while b[j]>x do dec(j); 54   if i<=j then 55    begin 56    swap(a[i],a[j]);swap(b[i],b[j]);swap(c[i],c[j]);swap(d[i],d[j]); 57    inc(i);dec(j); 58    end; 59  until i>j; 60  if i<r then sort1(i,r); 61  if j>l then sort1(l,j); 62  end; 63 procedure insert(x,y,z,w:longint); 64  begin 65  inc(tot); 66  with e[tot] do 67   begin 68   from:=x;go:=y;next:=head[x];head[x]:=tot;v1:=z;v2:=w; 69   end; 70  end; 71 procedure init; 72  begin 73  readln(n,m); 74  for i:=1 to n do fa[i]:=i; 75  for i:=1 to m do 76   begin 77   readln(x,y,a[i],b[i]); 78   xx:=find(x);yy:=find(y); 79   if xx<>yy then fa[xx]:=yy; 80   c[i]:=x;d[i]:=y; 81   end; 82  aa:=a; 83  sort(1,m);sort1(1,m); 84  end; 85 procedure dfs(x,t1,t2:longint); 86  var i,y:longint; 87  begin 88  v[x]:=true; 89  if x=n then begin flag:=true;ans:=min(ans,t1+t2);exit;end; 90  i:=head[x]; 91  while i<>0 do 92   begin 93   y:=e[i].go; 94   if not(v[y]) then dfs(y,max(t1,e[i].v1),max(t2,e[i].v2)); 95   if flag then break; 96   i:=e[i].next; 97   end; 98  end; 99 procedure mst;100  var i,j:longint;101  begin102  fillchar(v,sizeof(v),false);103  fillchar(head,sizeof(head),0);tot:=0;104  for i:=1 to n do fa[i]:=i;105  j:=1;106  for i:=1 to n-1 do107   begin108   while (j<=m) and ((a[j]>xx) or (find(d[j])=find(c[j])))do inc(j);109   if j>m then exit;110   fa[find(d[j])]:=find(c[j]);111   insert(c[j],d[j],a[j],b[j]);insert(d[j],c[j],a[j],b[j]);112   end;113  //for i:=1 to n do writeln(head[i]);114  flag:=false;115  dfs(1,0,0);116  end;117 procedure work1;118  begin119  //for i:=1 to m do write(aa[i], );writeln;120  l:=0;r:=m;121  while true do122   begin123   inc(l);124   while aa[l]=aa[l-1] do inc(l);//writeln(l, ,aa[l], ,r);125   inc(cnt);126   if l>r then break;127   xx:=aa[l];128   mst;129   while ans<=aa[r] do dec(r);130   inc(cnt);131   xx:=aa[r];132   mst;133   dec(r);while aa[r]=aa[r+1] do dec(r);134   end;135  writeln(ans);136  end;137 procedure work2;138  begin139  fillchar(hash,sizeof(hash),false);140  for i:=1 to 200 do141    begin142    repeat143     x:=random(m)+1;144    until not(hash[aa[x]]);145    xx:=aa[x];146    mst;147    end;148  writeln(ans);149  end;150 151 begin152  assign(input,forest.in);assign(output,forest.out);153  reset(input);rewrite(output);154  randomize;155  init;156  ans:=inf;157  if find(1)<>find(n) then writeln(-1)158  else if n*m<20000000 then work1 else work2;159  close(input);close(output);160 end.  
View Code

4.SPFA优化80分

  1 const inf=maxlongint>>2;maxn=100000+10;  2 type node=record  3      from,go,next,v1,v2:longint;  4      end;  5 var a,b,d,c1,c2,head,fa:array[0..maxn] of longint;  6     q:array[0..10*maxn] of longint;  7     e:array[0..maxn*2] of node;  8     v:array[0..maxn] of boolean;  9     i,j,xx,yy,l,z,w,tot,r,x,y:longint; 10     ans,n,m,mm:int64; 11     function find(x:longint):longint; 12      begin 13      if fa[x]<>x then fa[x]:=find(fa[x]); 14      exit(fa[x]); 15      end; 16     function max(x,y:longint):longint; 17      begin 18      if x>y then exit(x) else exit(y); 19      end; 20     function min(x,y:longint):longint; 21      begin 22      if x<y then exit(x) else exit(y); 23      end; 24     procedure swap(var x,y:longint); 25      var t:longint; 26      begin 27      t:=x;x:=y;y:=t; 28      end; 29  30 procedure sort(l,r:longint); 31  var i,j,x:longint; 32  begin 33  i:=l;j:=r;x:=a[(i+j)>>1]; 34  repeat 35   while a[i]<x do inc(i); 36   while a[j]>x do dec(j); 37   if i<=j then 38    begin 39    swap(a[i],a[j]);swap(b[i],b[j]);swap(c1[i],c1[j]);swap(c2[i],c2[j]); 40    inc(i);dec(j); 41    end; 42  until i>j; 43  if i<r then sort(i,r); 44  if j>l then sort(l,j); 45  end; 46 procedure insert(x,y,z,w:longint); 47  begin 48  inc(tot); 49  with e[tot] do 50   begin 51   from:=x;go:=y;next:=head[x];head[x]:=tot;v1:=z;v2:=w; 52   end; 53  end; 54 procedure spfa; 55  var i,x,y,h,t,tmp:longint; 56  begin 57  h:=0;t:=0; 58  for i:=1 to n do if v[i] then begin inc(t);q[t]:=i;end; 59  //for i:=1 to t do writeln(q[i]); 60  while h<t do 61   begin 62   inc(h); 63   x:=q[h];v[x]:=false; 64   i:=head[x]; 65   while i<>0 do 66    begin 67    y:=e[i].go; 68    tmp:=max(d[x],e[i].v2); 69    //writeln(e[i].v1, ,xx, ,tmp, ,d[y]); 70    if (e[i].v1<=xx) and (tmp<d[y]) then 71     begin 72     d[y]:=tmp;//writeln(d[y]); 73     if not(v[y]) then 74      begin 75      v[y]:=true; 76      inc(t);q[t]:=y; 77      end; 78     end; 79    i:=e[i].next; 80    end; 81   end; 82  end; 83 procedure init; 84  begin 85  readln(n,m);mm:=m;m:=0; 86  for i:=1 to n do fa[i]:=i; 87  for i:=1 to mm do 88   begin 89   readln(x,y,z,w); 90   xx:=find(x);yy:=find(y); 91   if xx<>yy then fa[xx]:=yy; 92   if x=y then continue; 93   inc(m);c1[m]:=x;c2[m]:=y;a[m]:=z;b[m]:=w; 94   insert(x,y,z,w);insert(y,x,z,w); 95   end; 96  sort(1,m); 97 // for i:=1 to m do writeln(c1[i], ,c2[i], ,a[i], ,b[i]); 98  end; 99 procedure main;100  begin101  d[1]:=0;102  for i:=2 to n do d[i]:=inf;103  //for i:=1 to n do writeln(i, ,d[i], ,head[i]);104  l:=1;r:=m;105  while true do106   begin107   fillchar(v,sizeof(v),false);108   while a[l]=a[l+1] do109    begin110    v[c1[l]]:=true;v[c2[l]]:=true;111    inc(l);112    end;113   v[c1[l]]:=true;v[c2[l]]:=true;114   xx:=a[l]; //writeln(xx);115   if l>r then break;116   spfa;117   //for i:=1 to n do writeln(i, ,d[i]);118   //if d[n]+xx=19923 then writeln(c1[l], ,c2[l], ,a[l], ,b[l]);119   //writeln(d[n], ,xx);120   ans:=min(ans,d[n]+xx);// writeln(d[n], ,l, ,r, ,xx);121   while ans<=a[r] do dec(r);122   inc(l);123   end;124  writeln(ans);125  end;126 begin127  assign(input,forest.in);assign(output,forest.out);128  reset(input);rewrite(output);129  init;130  ans:=inf<<1;131  if find(1)<>find(n) then writeln(-1) else main;132  close(input);close(output);133 end.   
View Code

5.SPFA再优化75分。。。

  1 const inf=maxlongint>>2;maxn=100000+10;  2 type node=record  3      from,go,next,v1,v2:longint;  4      end;  5 var a,b,d,c1,c2,head,fa:array[0..maxn] of longint;  6     q:array[0..10*maxn] of longint;  7     e:array[0..maxn*2] of node;  8     v:array[0..maxn] of boolean;  9     i,j,xx,yy,l,z,w,tot,r,x,y:longint; 10     ans,n,m,mm:int64; 11     function find(x:longint):longint; 12      begin 13      if fa[x]<>x then fa[x]:=find(fa[x]); 14      exit(fa[x]); 15      end; 16     function max(x,y:longint):longint; 17      begin 18      if x>y then exit(x) else exit(y); 19      end; 20     function min(x,y:longint):longint; 21      begin 22      if x<y then exit(x) else exit(y); 23      end; 24     procedure swap(var x,y:longint); 25      var t:longint; 26      begin 27      t:=x;x:=y;y:=t; 28      end; 29  30 procedure sort(l,r:longint); 31  var i,j,x:longint; 32  begin 33  i:=l;j:=r;x:=a[(i+j)>>1]; 34  repeat 35   while a[i]<x do inc(i); 36   while a[j]>x do dec(j); 37   if i<=j then 38    begin 39    swap(a[i],a[j]);swap(b[i],b[j]);swap(c1[i],c1[j]);swap(c2[i],c2[j]); 40    inc(i);dec(j); 41    end; 42  until i>j; 43  if i<r then sort(i,r); 44  if j>l then sort(l,j); 45  end; 46 procedure insert(x,y,z,w:longint); 47  begin 48  inc(tot); 49  with e[tot] do 50   begin 51   from:=x;go:=y;next:=head[x];head[x]:=tot;v1:=z;v2:=w; 52   end; 53  end; 54 procedure spfa; 55  var i,x,y,h,t,tmp:longint; 56  begin 57  h:=0;t:=0; 58  for i:=1 to n do if v[i] then begin inc(t);q[t]:=i;end; 59  //for i:=1 to t do writeln(q[i]); 60  while h<t do 61   begin 62   inc(h); 63   x:=q[h];v[x]:=false; 64   i:=head[x]; 65   while i<>0 do 66    begin 67    y:=e[i].go; 68    tmp:=max(d[x],e[i].v2); 69    //writeln(e[i].v1, ,xx, ,tmp, ,d[y]); 70    if (e[i].v1<=xx) and (tmp<d[y]) then 71     begin 72     d[y]:=tmp;//writeln(d[y]); 73     if not(v[y]) then 74      begin 75      v[y]:=true; 76      inc(t);q[t]:=y; 77      end; 78     end; 79    i:=e[i].next; 80    end; 81   end; 82  end; 83 procedure init; 84  begin 85  readln(n,m);mm:=m;m:=0; 86  for i:=1 to n do fa[i]:=i; 87  for i:=1 to mm do 88   begin 89   readln(x,y,z,w); 90   xx:=find(x);yy:=find(y); 91   if xx<>yy then fa[xx]:=yy; 92   //if x=y then continue; 93   inc(m);c1[m]:=x;c2[m]:=y;a[m]:=z;b[m]:=w; 94   insert(x,y,z,w);insert(y,x,z,w); 95   end; 96  sort(1,m); 97 // for i:=1 to m do writeln(c1[i], ,c2[i], ,a[i], ,b[i]); 98  end; 99 procedure main;100  begin101  d[1]:=0;102  for i:=2 to n do d[i]:=inf;103  //for i:=1 to n do writeln(i, ,d[i], ,head[i]);104  l:=1;r:=m;105  for i:=1 to n do fa[i]:=i;106  while find(1)<>find(n) do begin fa[find(c1[l])]:=find(c2[l]);inc(l);end;107  //writeln(l, ,find(1), ,find(n));108  while a[l]=a[l-1] do inc(l);109  v[1]:=true;xx:=a[l-1];spfa;ans:=min(ans,d[n]+xx);110  while true do111   begin112   fillchar(v,sizeof(v),false);113   while a[l]=a[l+1] do114    begin115    v[c1[l]]:=true;v[c2[l]]:=true;116    inc(l);117    end;118   v[c1[l]]:=true;v[c2[l]]:=true;119   xx:=a[l]; //writeln(xx);120   if l>r then break;121   spfa;122   //for i:=1 to n do writeln(i, ,d[i]);123   //if d[n]+xx=19923 then writeln(c1[l], ,c2[l], ,a[l], ,b[l]);124   //writeln(d[n], ,xx);125   ans:=min(ans,d[n]+xx);// writeln(d[n], ,l, ,r, ,xx);126   while ans<=a[r] do dec(r);127   inc(l);128   end;129  writeln(ans);130  end;131 begin132  assign(input,forest.in);assign(output,forest.out);133  reset(input);rewrite(output);134  init;135  ans:=inf<<1;136  if find(1)<>find(n) then writeln(-1) else main;137  close(input);close(output);138 end.    
View Code

6.原来发现数组开小了。。。100分,苦逼的调试

  1 const inf=maxlongint>>2;maxn=100000+10;  2 type node=record  3      from,go,next,v1,v2:longint;  4      end;  5 var a,b,d,c1,c2,head,fa:array[0..maxn] of longint;  6     q:array[0..100*maxn] of longint;  7     e:array[0..maxn*2] of node;  8     v:array[0..maxn] of boolean;  9     i,j,xx,yy,l,z,w,tot,r,x,y:longint; 10     ans,n,m,mm:int64; 11     function find(x:longint):longint; 12      begin 13      if fa[x]<>x then fa[x]:=find(fa[x]); 14      exit(fa[x]); 15      end; 16     function max(x,y:longint):longint; 17      begin 18      if x>y then exit(x) else exit(y); 19      end; 20     function min(x,y:longint):longint; 21      begin 22      if x<y then exit(x) else exit(y); 23      end; 24     procedure swap(var x,y:longint); 25      var t:longint; 26      begin 27      t:=x;x:=y;y:=t; 28      end; 29  30 procedure sort(l,r:longint); 31  var i,j,x:longint; 32  begin 33  i:=l;j:=r;x:=a[(i+j)>>1]; 34  repeat 35   while a[i]<x do inc(i); 36   while a[j]>x do dec(j); 37   if i<=j then 38    begin 39    swap(a[i],a[j]);swap(b[i],b[j]);swap(c1[i],c1[j]);swap(c2[i],c2[j]); 40    inc(i);dec(j); 41    end; 42  until i>j; 43  if i<r then sort(i,r); 44  if j>l then sort(l,j); 45  end; 46 procedure insert(x,y,z,w:longint); 47  begin 48  inc(tot); 49  with e[tot] do 50   begin 51   from:=x;go:=y;next:=head[x];head[x]:=tot;v1:=z;v2:=w; 52   end; 53  end; 54 procedure spfa; 55  var i,x,y,h,t,tmp:longint; 56  begin 57  //writeln(1); 58  h:=0;t:=0; 59  for i:=1 to n do if v[i] then begin inc(t);q[t]:=i;end; 60  //for i:=1 to t do writeln(q[i]); 61  while h<t do 62   begin 63   inc(h); 64   x:=q[h];v[x]:=false; //writeln(x); 65   i:=head[x]; 66   while i<>0 do 67    begin 68    y:=e[i].go; 69    tmp:=max(d[x],e[i].v2); 70    //writeln(e[i].v1, ,xx, ,tmp, ,d[y]); 71    if (e[i].v1<=xx) and (tmp<d[y]) then 72     begin 73     d[y]:=tmp;//writeln(d[y]); 74     if not(v[y]) then 75      begin 76      v[y]:=true; 77      inc(t);q[t]:=y; 78      end; 79     end; 80    i:=e[i].next; 81    end; 82   end; 83  end; 84 procedure init; 85  begin 86  readln(n,m);mm:=m;m:=0; 87  for i:=1 to n do fa[i]:=i; 88  for i:=1 to mm do 89   begin 90   readln(x,y,z,w); 91   xx:=find(x);yy:=find(y); 92   if xx<>yy then fa[xx]:=yy; 93   if x=y then continue; 94   inc(m);c1[m]:=x;c2[m]:=y;a[m]:=z;b[m]:=w; 95   insert(x,y,z,w);insert(y,x,z,w); 96   end; 97  sort(1,m);//writeln(m); 98  //for i:=1 to m do writeln(i, ,c1[i], ,c2[i], ,a[i], ,b[i]); 99  end;100 procedure main;101  begin102  d[1]:=0;103  for i:=2 to n do d[i]:=inf;104  //for i:=1 to n do writeln(i, ,d[i], ,head[i]);105  l:=1;r:=m;106  for i:=1 to n do fa[i]:=i;107  while find(1)<>find(n) do108   begin109   //writeln(l, ,find(1), ,find(n));110   //writeln(c1[l], ,c2[l]);111   xx:=find(c1[l]);yy:=find(c2[l]);112   if xx<>yy then fa[xx]:=yy;113   inc(l);114   end;115  //writeln(l, ,find(1), ,find(n));116  while a[l]=a[l-1] do inc(l);//writeln(l);117  v[1]:=true;xx:=a[l-1];//writeln(xx);118  spfa;119  //for i:=1 to n do writeln(i, ,d[i]);120  ans:=min(ans,d[n]+xx);//writeln(            ,ans);121  while true do122   begin123   //writeln(         ,ans);124   fillchar(v,sizeof(v),false);125   if l>r then break;126   while a[l]=a[l+1] do127    begin128    v[c1[l]]:=true;v[c2[l]]:=true;129    inc(l);130    end;131   v[c1[l]]:=true;v[c2[l]]:=true;132   xx:=a[l]; //writeln(xx);133   if l>r then break;134   spfa;135   //for i:=1 to n do writeln(i, ,d[i]);136   //if d[n]+xx=19923 then writeln(c1[l], ,c2[l], ,a[l], ,b[l]);137   //writeln(d[n], ,xx);138   ans:=min(ans,d[n]+xx);//writeln(d[n], ,l, ,r, ,xx);139   while ans<=a[r] do dec(r);140   inc(l);141   end;142  writeln(ans);143  end;144 begin145  assign(input,forest.in);assign(output,forest.out);146  reset(input);rewrite(output);147  init;148  ans:=inf<<1;149  if find(1)<>find(n) then writeln(-1) else main;150  close(input);close(output);151 end.  
View Code

7.去掉调试更清晰。。。

  1 const inf=maxlongint>>2;maxn=100000+10;  2 type node=record  3      from,go,next,v1,v2:longint;  4      end;  5 var a,b,d,c1,c2,head,fa:array[0..maxn] of longint;  6     q:array[0..100*maxn] of longint;  7     e:array[0..maxn*2] of node;  8     v:array[0..maxn] of boolean;  9     i,j,xx,yy,l,z,w,tot,r,x,y:longint; 10     ans,n,m,mm:int64; 11     function find(x:longint):longint; 12      begin 13      if fa[x]<>x then fa[x]:=find(fa[x]); 14      exit(fa[x]); 15      end; 16     function max(x,y:longint):longint; 17      begin 18      if x>y then exit(x) else exit(y); 19      end; 20     function min(x,y:longint):longint; 21      begin 22      if x<y then exit(x) else exit(y); 23      end; 24     procedure swap(var x,y:longint); 25      var t:longint; 26      begin 27      t:=x;x:=y;y:=t; 28      end; 29  30 procedure sort(l,r:longint); 31  var i,j,x:longint; 32  begin 33  i:=l;j:=r;x:=a[(i+j)>>1]; 34  repeat 35   while a[i]<x do inc(i); 36   while a[j]>x do dec(j); 37   if i<=j then 38    begin 39    swap(a[i],a[j]);swap(b[i],b[j]);swap(c1[i],c1[j]);swap(c2[i],c2[j]); 40    inc(i);dec(j); 41    end; 42  until i>j; 43  if i<r then sort(i,r); 44  if j>l then sort(l,j); 45  end; 46 procedure insert(x,y,z,w:longint); 47  begin 48  inc(tot); 49  with e[tot] do 50   begin 51   from:=x;go:=y;next:=head[x];head[x]:=tot;v1:=z;v2:=w; 52   end; 53  end; 54 procedure spfa; 55  var i,x,y,h,t,tmp:longint; 56  begin 57  h:=0;t:=0; 58  for i:=1 to n do if v[i] then begin inc(t);q[t]:=i;end; 59  while h<t do 60   begin 61   inc(h); 62   x:=q[h];v[x]:=false; 63   i:=head[x]; 64   while i<>0 do 65    begin 66    y:=e[i].go; 67    tmp:=max(d[x],e[i].v2); 68    if (e[i].v1<=xx) and (tmp<d[y]) then 69     begin 70     d[y]:=tmp; 71     if not(v[y]) then 72      begin 73      v[y]:=true; 74      inc(t);q[t]:=y; 75      end; 76     end; 77    i:=e[i].next; 78    end; 79   end; 80  end; 81 procedure init; 82  begin 83  readln(n,m);mm:=m;m:=0; 84  for i:=1 to n do fa[i]:=i; 85  for i:=1 to mm do 86   begin 87   readln(x,y,z,w); 88   xx:=find(x);yy:=find(y); 89   if xx<>yy then fa[xx]:=yy; 90   if x=y then continue; 91   inc(m);c1[m]:=x;c2[m]:=y;a[m]:=z;b[m]:=w; 92   insert(x,y,z,w);insert(y,x,z,w); 93   end; 94  sort(1,m); 95  96  end; 97 procedure main; 98  begin 99  d[1]:=0;100  for i:=2 to n do d[i]:=inf;101  l:=1;r:=m;102  for i:=1 to n do fa[i]:=i;103  while find(1)<>find(n) do104   begin105   xx:=find(c1[l]);yy:=find(c2[l]);106   if xx<>yy then fa[xx]:=yy;107   inc(l);108   end;109  while a[l]=a[l-1] do inc(l);110  v[1]:=true;xx:=a[l-1];111  spfa;112  ans:=min(ans,d[n]+xx);113  while true do114   begin115   fillchar(v,sizeof(v),false);116   if l>r then break;117   while a[l]=a[l+1] do118    begin119    v[c1[l]]:=true;v[c2[l]]:=true;120    inc(l);121    end;122   v[c1[l]]:=true;v[c2[l]]:=true;123   xx:=a[l];124   if l>r then break;125   spfa;126   ans:=min(ans,d[n]+xx);127   while ans<=a[r] do dec(r);128   inc(l);129   end;130  writeln(ans);131  end;132 begin133  assign(input,forest.in);assign(output,forest.out);134  reset(input);rewrite(output);135  init;136  ans:=inf<<1;137  if find(1)<>find(n) then writeln(-1) else main;138  close(input);close(output);139 end.     
View Code