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啊。。。)

 const inf=maxlongint>>;maxn=+;
type node=record
from,go,next,v1,v2:longint;
end;
var a,b,d1,d2,head,fa:array[..maxn] of longint;
q:array[..*maxn] of longint;
e:array[..maxn*] of node;
v:array[..maxn] of boolean;
i,j,xx,yy,ll,tot,rr,x,y,point,mid:longint;
ans,n,m:int64;
function find(x:longint):longint;
begin
if fa[x]<>x then fa[x]:=find(fa[x]);
exit(fa[x]);
end;
function max(x,y:longint):longint;
begin
if x>y then exit(x) else exit(y);
end;
procedure sort1(l,r:longint);
var i,j,x,y:longint;
begin
i:=l;j:=r;x:=a[(i+j)>>];
repeat
while a[i]>x do inc(i);
while a[j]<x do dec(j);
if i<=j then
begin
y:=a[i];a[i]:=a[j];a[j]:=y;
inc(i);dec(j);
end;
until i>j;
if i<r then sort1(i,r);
if j>l then sort1(l,j);
end;
procedure sort2(l,r:longint);
var i,j,x,y:longint;
begin
i:=l;j:=r;x:=b[(i+j)>>];
repeat
while b[i]<x do inc(i);
while b[j]>x do dec(j);
if i<=j then
begin
y:=b[i];b[i]:=b[j];b[j]:=y;
inc(i);dec(j);
end;
until i>j;
if i<r then sort2(i,r);
if j>l then sort2(l,j);
end;
procedure insert(x,y,z,w:longint);
begin
inc(tot);
with e[tot] do
begin
from:=x;go:=y;next:=head[x];head[x]:=tot;v1:=z;v2:=w;
end;
end;
procedure spfa;
var i,x,y,h,t,tmp1,tmp2:longint;
begin
for i:= to n do d1[i]:=inf;
for i:= to n do d2[i]:=inf;
fillchar(v,sizeof(v),false);
h:=;t:=;q[]:=;d1[]:=;d2[]:=;
while h<t do
begin
inc(h);
x:=q[h];v[x]:=false;
i:=head[x];
while i<> do
begin
y:=e[i].go;
tmp1:=max(d1[x],e[i].v1);
tmp2:=max(d2[x],e[i].v2);
if (tmp1<=xx) and (tmp2<=yy) and (tmp2<d2[y]) then
begin
d1[y]:=tmp1;d2[y]:=tmp2;
if not(v[y]) then
begin
v[y]:=true;
inc(t);q[t]:=y;
end;
end;
i:=e[i].next;
end;
end;
end;
procedure init;
begin
readln(n,m);
for i:= to n do fa[i]:=i;
for i:= to m do
begin
readln(x,y,a[i],b[i]);
xx:=find(x);yy:=find(y);
if xx<>yy then fa[xx]:=yy;
insert(x,y,a[i],b[i]);insert(y,x,a[i],b[i]);
end;
sort1(,m);
sort2(,m);
end;
procedure work1;
begin
xx:=a[];point:=;
while true do
begin
ll:=;rr:=m;
while ll<rr do
begin
mid:=(ll+rr)>>;
yy:=b[mid];
spfa;
if d2[n]<>inf then rr:=mid else ll:=mid+;
end;
inc(point);
while (point<=m) and (d1[n]<a[point]) do inc(point);
if point>m then break;
xx:=a[point];
if d1[n]+d2[n]<ans then ans:=d1[n]+d2[n];
end;
writeln(ans);
end;
procedure work2;
begin
for i:= to do
begin
xx:=random(a[])+;
yy:=random(b[m])+;
spfa;
if d1[n]+d2[n]<ans then ans:=d1[n]+d2[n];
end;
writeln(ans);
end;
begin
assign(input,'forest.in');assign(output,'forest.out');
reset(input);rewrite(output);
init;
ans:=inf;
if find()<>find(n) then writeln('-1') else if n*m*< then work1 else work2;
close(input);close(output);
end.

2.朴素SPFA55分

 const inf=maxlongint>>;maxn=+;
type node=record
from,go,next,v1,v2:longint;
end;
var a,b,d1,d2,head,fa:array[..maxn] of longint;
q:array[..*maxn] of longint;
e:array[..maxn*] of node;
v:array[..maxn] of boolean;
i,j,xx,yy,l,tot,r,x,y:longint;
ans,n,m:int64;
function find(x:longint):longint;
begin
if fa[x]<>x then fa[x]:=find(fa[x]);
exit(fa[x]);
end;
function max(x,y:longint):longint;
begin
if x>y then exit(x) else exit(y);
end;
function min(x,y:longint):longint;
begin
if x<y then exit(x) else exit(y);
end; procedure sort(l,r:longint);
var i,j,x,y:longint;
begin
i:=l;j:=r;x:=a[(i+j)>>];
repeat
while a[i]<x do inc(i);
while a[j]>x do dec(j);
if i<=j then
begin
y:=a[i];a[i]:=a[j];a[j]:=y;
inc(i);dec(j);
end;
until i>j;
if i<r then sort(i,r);
if j>l then sort(l,j);
end;
procedure insert(x,y,z,w:longint);
begin
inc(tot);
with e[tot] do
begin
from:=x;go:=y;next:=head[x];head[x]:=tot;v1:=z;v2:=w;
end;
end;
procedure spfa;
var i,x,y,h,t,tmp1,tmp2:longint;
begin
for i:= to n do d1[i]:=inf;
for i:= to n do d2[i]:=inf;
fillchar(v,sizeof(v),false);
h:=;t:=;q[]:=;d1[]:=;d2[]:=;
while h<t do
begin
inc(h);
x:=q[h];v[x]:=false;
i:=head[x];
while i<> do
begin
y:=e[i].go;
tmp1:=max(d1[x],e[i].v1);
tmp2:=max(d2[x],e[i].v2);
if (tmp1<=xx) and (tmp2<d2[y]) then
begin
d1[y]:=tmp1;d2[y]:=tmp2;
if not(v[y]) then
begin
v[y]:=true;
inc(t);q[t]:=y;
end;
end;
i:=e[i].next;
end;
end;
end;
procedure init;
begin
readln(n,m);
for i:= to n do fa[i]:=i;
for i:= to m do
begin
readln(x,y,a[i],b[i]);
xx:=find(x);yy:=find(y);
if xx<>yy then fa[xx]:=yy;
insert(x,y,a[i],b[i]);insert(y,x,a[i],b[i]);
end;
sort(,m);
end;
procedure work1;
begin
xx:=a[];l:=;r:=m;
while true do
begin
while a[l]=a[l-] do inc(l);
inc(l);xx:=a[l];
if l>r then break;
spfa;
while d1[n]+d2[n]<=a[r] do dec(r);
ans:=min(ans,d1[n]+d2[n]);
xx:=a[r];
spfa;
ans:=min(ans,d1[n]+d2[n]);
while d1[n]<=a[r] do dec(r);
end;
writeln(ans);
end;
begin
assign(input,'forest.in');assign(output,'forest.out');
reset(input);rewrite(output);
init;
ans:=inf;
if find()<>find(n) then writeln('-1') else work1;
close(input);close(output);
end.

3.MST40分

 const inf=maxlongint>>;maxn=+;
type node=record
from,go,next,v1,v2:longint;
end;
arr=array[..maxn] of longint;
var a,b,c,d,head,fa,aa:arr;
e:array[..maxn*] of node;
v,hash:array[..maxn] of boolean;
i,j,xx,yy,l,tot,r,x,y,cnt:longint;
ans,n,m:int64;
flag:boolean;
function find(x:longint):longint;
begin
if fa[x]<>x then fa[x]:=find(fa[x]);
exit(fa[x]);
end;
function max(x,y:longint):longint;
begin
if x>y then exit(x) else exit(y);
end;
function min(x,y:longint):longint;
begin
if x<y then exit(x) else exit(y);
end;
procedure swap(var x,y:longint);
var t:longint;
begin
t:=x;x:=y;y:=t;
end; procedure sort(l,r:longint);
var i,j,x:longint;
begin
i:=l;j:=r;x:=aa[(i+j)>>];
repeat
while aa[i]<x do inc(i);
while aa[j]>x do dec(j);
if i<=j then
begin
swap(aa[i],aa[j]);
inc(i);dec(j);
end;
until i>j;
if i<r then sort(i,r);
if j>l then sort(l,j);
end;
procedure sort1(l,r:longint);
var i,j,x:longint;
begin
i:=l;j:=r;x:=b[(i+j)>>];
repeat
while b[i]<x do inc(i);
while b[j]>x do dec(j);
if i<=j then
begin
swap(a[i],a[j]);swap(b[i],b[j]);swap(c[i],c[j]);swap(d[i],d[j]);
inc(i);dec(j);
end;
until i>j;
if i<r then sort1(i,r);
if j>l then sort1(l,j);
end;
procedure insert(x,y,z,w:longint);
begin
inc(tot);
with e[tot] do
begin
from:=x;go:=y;next:=head[x];head[x]:=tot;v1:=z;v2:=w;
end;
end;
procedure init;
begin
readln(n,m);
for i:= to n do fa[i]:=i;
for i:= to m do
begin
readln(x,y,a[i],b[i]);
xx:=find(x);yy:=find(y);
if xx<>yy then fa[xx]:=yy;
c[i]:=x;d[i]:=y;
end;
aa:=a;
sort(,m);sort1(,m);
end;
procedure dfs(x,t1,t2:longint);
var i,y:longint;
begin
v[x]:=true;
if x=n then begin flag:=true;ans:=min(ans,t1+t2);exit;end;
i:=head[x];
while i<> do
begin
y:=e[i].go;
if not(v[y]) then dfs(y,max(t1,e[i].v1),max(t2,e[i].v2));
if flag then break;
i:=e[i].next;
end;
end;
procedure mst;
var i,j:longint;
begin
fillchar(v,sizeof(v),false);
fillchar(head,sizeof(head),);tot:=;
for i:= to n do fa[i]:=i;
j:=;
for i:= to n- do
begin
while (j<=m) and ((a[j]>xx) or (find(d[j])=find(c[j])))do inc(j);
if j>m then exit;
fa[find(d[j])]:=find(c[j]);
insert(c[j],d[j],a[j],b[j]);insert(d[j],c[j],a[j],b[j]);
end;
//for i:= to n do writeln(head[i]);
flag:=false;
dfs(,,);
end;
procedure work1;
begin
//for i:= to m do write(aa[i],' ');writeln;
l:=;r:=m;
while true do
begin
inc(l);
while aa[l]=aa[l-] do inc(l);//writeln(l,' ',aa[l],' ',r);
inc(cnt);
if l>r then break;
xx:=aa[l];
mst;
while ans<=aa[r] do dec(r);
inc(cnt);
xx:=aa[r];
mst;
dec(r);while aa[r]=aa[r+] do dec(r);
end;
writeln(ans);
end;
procedure work2;
begin
fillchar(hash,sizeof(hash),false);
for i:= to do
begin
repeat
x:=random(m)+;
until not(hash[aa[x]]);
xx:=aa[x];
mst;
end;
writeln(ans);
end; begin
assign(input,'forest.in');assign(output,'forest.out');
reset(input);rewrite(output);
randomize;
init;
ans:=inf;
if find()<>find(n) then writeln('-1')
else if n*m< then work1 else work2;
close(input);close(output);
end.

4.SPFA优化80分

 const inf=maxlongint>>;maxn=+;
type node=record
from,go,next,v1,v2:longint;
end;
var a,b,d,c1,c2,head,fa:array[..maxn] of longint;
q:array[..*maxn] of longint;
e:array[..maxn*] of node;
v:array[..maxn] of boolean;
i,j,xx,yy,l,z,w,tot,r,x,y:longint;
ans,n,m,mm:int64;
function find(x:longint):longint;
begin
if fa[x]<>x then fa[x]:=find(fa[x]);
exit(fa[x]);
end;
function max(x,y:longint):longint;
begin
if x>y then exit(x) else exit(y);
end;
function min(x,y:longint):longint;
begin
if x<y then exit(x) else exit(y);
end;
procedure swap(var x,y:longint);
var t:longint;
begin
t:=x;x:=y;y:=t;
end; procedure sort(l,r:longint);
var i,j,x:longint;
begin
i:=l;j:=r;x:=a[(i+j)>>];
repeat
while a[i]<x do inc(i);
while a[j]>x do dec(j);
if i<=j then
begin
swap(a[i],a[j]);swap(b[i],b[j]);swap(c1[i],c1[j]);swap(c2[i],c2[j]);
inc(i);dec(j);
end;
until i>j;
if i<r then sort(i,r);
if j>l then sort(l,j);
end;
procedure insert(x,y,z,w:longint);
begin
inc(tot);
with e[tot] do
begin
from:=x;go:=y;next:=head[x];head[x]:=tot;v1:=z;v2:=w;
end;
end;
procedure spfa;
var i,x,y,h,t,tmp:longint;
begin
h:=;t:=;
for i:= to n do if v[i] then begin inc(t);q[t]:=i;end;
//for i:= to t do writeln(q[i]);
while h<t do
begin
inc(h);
x:=q[h];v[x]:=false;
i:=head[x];
while i<> do
begin
y:=e[i].go;
tmp:=max(d[x],e[i].v2);
//writeln(e[i].v1,' ',xx,' ',tmp,' ',d[y]);
if (e[i].v1<=xx) and (tmp<d[y]) then
begin
d[y]:=tmp;//writeln(d[y]);
if not(v[y]) then
begin
v[y]:=true;
inc(t);q[t]:=y;
end;
end;
i:=e[i].next;
end;
end;
end;
procedure init;
begin
readln(n,m);mm:=m;m:=;
for i:= to n do fa[i]:=i;
for i:= to mm do
begin
readln(x,y,z,w);
xx:=find(x);yy:=find(y);
if xx<>yy then fa[xx]:=yy;
if x=y then continue;
inc(m);c1[m]:=x;c2[m]:=y;a[m]:=z;b[m]:=w;
insert(x,y,z,w);insert(y,x,z,w);
end;
sort(,m);
// for i:= to m do writeln(c1[i],' ',c2[i],' ',a[i],' ',b[i]);
end;
procedure main;
begin
d[]:=;
for i:= to n do d[i]:=inf;
//for i:= to n do writeln(i,' ',d[i],' ',head[i]);
l:=;r:=m;
while true do
begin
fillchar(v,sizeof(v),false);
while a[l]=a[l+] do
begin
v[c1[l]]:=true;v[c2[l]]:=true;
inc(l);
end;
v[c1[l]]:=true;v[c2[l]]:=true;
xx:=a[l]; //writeln(xx);
if l>r then break;
spfa;
//for i:= to n do writeln(i,' ',d[i]);
//if d[n]+xx= then writeln(c1[l],' ',c2[l],' ',a[l],' ',b[l]);
//writeln(d[n],' ',xx);
ans:=min(ans,d[n]+xx);// writeln(d[n],' ',l,' ',r,' ',xx);
while ans<=a[r] do dec(r);
inc(l);
end;
writeln(ans);
end;
begin
assign(input,'forest.in');assign(output,'forest.out');
reset(input);rewrite(output);
init;
ans:=inf<<;
if find()<>find(n) then writeln('-1') else main;
close(input);close(output);
end.

5.SPFA再优化75分。。。

 const inf=maxlongint>>;maxn=+;
type node=record
from,go,next,v1,v2:longint;
end;
var a,b,d,c1,c2,head,fa:array[..maxn] of longint;
q:array[..*maxn] of longint;
e:array[..maxn*] of node;
v:array[..maxn] of boolean;
i,j,xx,yy,l,z,w,tot,r,x,y:longint;
ans,n,m,mm:int64;
function find(x:longint):longint;
begin
if fa[x]<>x then fa[x]:=find(fa[x]);
exit(fa[x]);
end;
function max(x,y:longint):longint;
begin
if x>y then exit(x) else exit(y);
end;
function min(x,y:longint):longint;
begin
if x<y then exit(x) else exit(y);
end;
procedure swap(var x,y:longint);
var t:longint;
begin
t:=x;x:=y;y:=t;
end; procedure sort(l,r:longint);
var i,j,x:longint;
begin
i:=l;j:=r;x:=a[(i+j)>>];
repeat
while a[i]<x do inc(i);
while a[j]>x do dec(j);
if i<=j then
begin
swap(a[i],a[j]);swap(b[i],b[j]);swap(c1[i],c1[j]);swap(c2[i],c2[j]);
inc(i);dec(j);
end;
until i>j;
if i<r then sort(i,r);
if j>l then sort(l,j);
end;
procedure insert(x,y,z,w:longint);
begin
inc(tot);
with e[tot] do
begin
from:=x;go:=y;next:=head[x];head[x]:=tot;v1:=z;v2:=w;
end;
end;
procedure spfa;
var i,x,y,h,t,tmp:longint;
begin
h:=;t:=;
for i:= to n do if v[i] then begin inc(t);q[t]:=i;end;
//for i:= to t do writeln(q[i]);
while h<t do
begin
inc(h);
x:=q[h];v[x]:=false;
i:=head[x];
while i<> do
begin
y:=e[i].go;
tmp:=max(d[x],e[i].v2);
//writeln(e[i].v1,' ',xx,' ',tmp,' ',d[y]);
if (e[i].v1<=xx) and (tmp<d[y]) then
begin
d[y]:=tmp;//writeln(d[y]);
if not(v[y]) then
begin
v[y]:=true;
inc(t);q[t]:=y;
end;
end;
i:=e[i].next;
end;
end;
end;
procedure init;
begin
readln(n,m);mm:=m;m:=;
for i:= to n do fa[i]:=i;
for i:= to mm do
begin
readln(x,y,z,w);
xx:=find(x);yy:=find(y);
if xx<>yy then fa[xx]:=yy;
//if x=y then continue;
inc(m);c1[m]:=x;c2[m]:=y;a[m]:=z;b[m]:=w;
insert(x,y,z,w);insert(y,x,z,w);
end;
sort(,m);
// for i:= to m do writeln(c1[i],' ',c2[i],' ',a[i],' ',b[i]);
end;
procedure main;
begin
d[]:=;
for i:= to n do d[i]:=inf;
//for i:= to n do writeln(i,' ',d[i],' ',head[i]);
l:=;r:=m;
for i:= to n do fa[i]:=i;
while find()<>find(n) do begin fa[find(c1[l])]:=find(c2[l]);inc(l);end;
//writeln(l,' ',find(),' ',find(n));
while a[l]=a[l-] do inc(l);
v[]:=true;xx:=a[l-];spfa;ans:=min(ans,d[n]+xx);
while true do
begin
fillchar(v,sizeof(v),false);
while a[l]=a[l+] do
begin
v[c1[l]]:=true;v[c2[l]]:=true;
inc(l);
end;
v[c1[l]]:=true;v[c2[l]]:=true;
xx:=a[l]; //writeln(xx);
if l>r then break;
spfa;
//for i:= to n do writeln(i,' ',d[i]);
//if d[n]+xx= then writeln(c1[l],' ',c2[l],' ',a[l],' ',b[l]);
//writeln(d[n],' ',xx);
ans:=min(ans,d[n]+xx);// writeln(d[n],' ',l,' ',r,' ',xx);
while ans<=a[r] do dec(r);
inc(l);
end;
writeln(ans);
end;
begin
assign(input,'forest.in');assign(output,'forest.out');
reset(input);rewrite(output);
init;
ans:=inf<<;
if find()<>find(n) then writeln('-1') else main;
close(input);close(output);
end.

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

 const inf=maxlongint>>;maxn=+;
type node=record
from,go,next,v1,v2:longint;
end;
var a,b,d,c1,c2,head,fa:array[..maxn] of longint;
q:array[..*maxn] of longint;
e:array[..maxn*] of node;
v:array[..maxn] of boolean;
i,j,xx,yy,l,z,w,tot,r,x,y:longint;
ans,n,m,mm:int64;
function find(x:longint):longint;
begin
if fa[x]<>x then fa[x]:=find(fa[x]);
exit(fa[x]);
end;
function max(x,y:longint):longint;
begin
if x>y then exit(x) else exit(y);
end;
function min(x,y:longint):longint;
begin
if x<y then exit(x) else exit(y);
end;
procedure swap(var x,y:longint);
var t:longint;
begin
t:=x;x:=y;y:=t;
end; procedure sort(l,r:longint);
var i,j,x:longint;
begin
i:=l;j:=r;x:=a[(i+j)>>];
repeat
while a[i]<x do inc(i);
while a[j]>x do dec(j);
if i<=j then
begin
swap(a[i],a[j]);swap(b[i],b[j]);swap(c1[i],c1[j]);swap(c2[i],c2[j]);
inc(i);dec(j);
end;
until i>j;
if i<r then sort(i,r);
if j>l then sort(l,j);
end;
procedure insert(x,y,z,w:longint);
begin
inc(tot);
with e[tot] do
begin
from:=x;go:=y;next:=head[x];head[x]:=tot;v1:=z;v2:=w;
end;
end;
procedure spfa;
var i,x,y,h,t,tmp:longint;
begin
//writeln();
h:=;t:=;
for i:= to n do if v[i] then begin inc(t);q[t]:=i;end;
//for i:= to t do writeln(q[i]);
while h<t do
begin
inc(h);
x:=q[h];v[x]:=false; //writeln(x);
i:=head[x];
while i<> do
begin
y:=e[i].go;
tmp:=max(d[x],e[i].v2);
//writeln(e[i].v1,' ',xx,' ',tmp,' ',d[y]);
if (e[i].v1<=xx) and (tmp<d[y]) then
begin
d[y]:=tmp;//writeln(d[y]);
if not(v[y]) then
begin
v[y]:=true;
inc(t);q[t]:=y;
end;
end;
i:=e[i].next;
end;
end;
end;
procedure init;
begin
readln(n,m);mm:=m;m:=;
for i:= to n do fa[i]:=i;
for i:= to mm do
begin
readln(x,y,z,w);
xx:=find(x);yy:=find(y);
if xx<>yy then fa[xx]:=yy;
if x=y then continue;
inc(m);c1[m]:=x;c2[m]:=y;a[m]:=z;b[m]:=w;
insert(x,y,z,w);insert(y,x,z,w);
end;
sort(,m);//writeln(m);
//for i:= to m do writeln(i,' ',c1[i],' ',c2[i],' ',a[i],' ',b[i]);
end;
procedure main;
begin
d[]:=;
for i:= to n do d[i]:=inf;
//for i:= to n do writeln(i,' ',d[i],' ',head[i]);
l:=;r:=m;
for i:= to n do fa[i]:=i;
while find()<>find(n) do
begin
//writeln(l,' ',find(),' ',find(n));
//writeln(c1[l],' ',c2[l]);
xx:=find(c1[l]);yy:=find(c2[l]);
if xx<>yy then fa[xx]:=yy;
inc(l);
end;
//writeln(l,' ',find(),' ',find(n));
while a[l]=a[l-] do inc(l);//writeln(l);
v[]:=true;xx:=a[l-];//writeln(xx);
spfa;
//for i:= to n do writeln(i,' ',d[i]);
ans:=min(ans,d[n]+xx);//writeln(' ',ans);
while true do
begin
//writeln(' ',ans);
fillchar(v,sizeof(v),false);
if l>r then break;
while a[l]=a[l+] do
begin
v[c1[l]]:=true;v[c2[l]]:=true;
inc(l);
end;
v[c1[l]]:=true;v[c2[l]]:=true;
xx:=a[l]; //writeln(xx);
if l>r then break;
spfa;
//for i:= to n do writeln(i,' ',d[i]);
//if d[n]+xx= then writeln(c1[l],' ',c2[l],' ',a[l],' ',b[l]);
//writeln(d[n],' ',xx);
ans:=min(ans,d[n]+xx);//writeln(d[n],' ',l,' ',r,' ',xx);
while ans<=a[r] do dec(r);
inc(l);
end;
writeln(ans);
end;
begin
assign(input,'forest.in');assign(output,'forest.out');
reset(input);rewrite(output);
init;
ans:=inf<<;
if find()<>find(n) then writeln('-1') else main;
close(input);close(output);
end.

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

 const inf=maxlongint>>;maxn=+;
type node=record
from,go,next,v1,v2:longint;
end;
var a,b,d,c1,c2,head,fa:array[..maxn] of longint;
q:array[..*maxn] of longint;
e:array[..maxn*] of node;
v:array[..maxn] of boolean;
i,j,xx,yy,l,z,w,tot,r,x,y:longint;
ans,n,m,mm:int64;
function find(x:longint):longint;
begin
if fa[x]<>x then fa[x]:=find(fa[x]);
exit(fa[x]);
end;
function max(x,y:longint):longint;
begin
if x>y then exit(x) else exit(y);
end;
function min(x,y:longint):longint;
begin
if x<y then exit(x) else exit(y);
end;
procedure swap(var x,y:longint);
var t:longint;
begin
t:=x;x:=y;y:=t;
end; procedure sort(l,r:longint);
var i,j,x:longint;
begin
i:=l;j:=r;x:=a[(i+j)>>];
repeat
while a[i]<x do inc(i);
while a[j]>x do dec(j);
if i<=j then
begin
swap(a[i],a[j]);swap(b[i],b[j]);swap(c1[i],c1[j]);swap(c2[i],c2[j]);
inc(i);dec(j);
end;
until i>j;
if i<r then sort(i,r);
if j>l then sort(l,j);
end;
procedure insert(x,y,z,w:longint);
begin
inc(tot);
with e[tot] do
begin
from:=x;go:=y;next:=head[x];head[x]:=tot;v1:=z;v2:=w;
end;
end;
procedure spfa;
var i,x,y,h,t,tmp:longint;
begin
h:=;t:=;
for i:= to n do if v[i] then begin inc(t);q[t]:=i;end;
while h<t do
begin
inc(h);
x:=q[h];v[x]:=false;
i:=head[x];
while i<> do
begin
y:=e[i].go;
tmp:=max(d[x],e[i].v2);
if (e[i].v1<=xx) and (tmp<d[y]) then
begin
d[y]:=tmp;
if not(v[y]) then
begin
v[y]:=true;
inc(t);q[t]:=y;
end;
end;
i:=e[i].next;
end;
end;
end;
procedure init;
begin
readln(n,m);mm:=m;m:=;
for i:= to n do fa[i]:=i;
for i:= to mm do
begin
readln(x,y,z,w);
xx:=find(x);yy:=find(y);
if xx<>yy then fa[xx]:=yy;
if x=y then continue;
inc(m);c1[m]:=x;c2[m]:=y;a[m]:=z;b[m]:=w;
insert(x,y,z,w);insert(y,x,z,w);
end;
sort(,m); end;
procedure main;
begin
d[]:=;
for i:= to n do d[i]:=inf;
l:=;r:=m;
for i:= to n do fa[i]:=i;
while find()<>find(n) do
begin
xx:=find(c1[l]);yy:=find(c2[l]);
if xx<>yy then fa[xx]:=yy;
inc(l);
end;
while a[l]=a[l-] do inc(l);
v[]:=true;xx:=a[l-];
spfa;
ans:=min(ans,d[n]+xx);
while true do
begin
fillchar(v,sizeof(v),false);
if l>r then break;
while a[l]=a[l+] do
begin
v[c1[l]]:=true;v[c2[l]]:=true;
inc(l);
end;
v[c1[l]]:=true;v[c2[l]]:=true;
xx:=a[l];
if l>r then break;
spfa;
ans:=min(ans,d[n]+xx);
while ans<=a[r] do dec(r);
inc(l);
end;
writeln(ans);
end;
begin
assign(input,'forest.in');assign(output,'forest.out');
reset(input);rewrite(output);
init;
ans:=inf<<;
if find()<>find(n) then writeln('-1') else main;
close(input);close(output);
end.

NOI2014 魔法森林的更多相关文章

  1. bzoj 3669: [Noi2014]魔法森林 动态树

    3669: [Noi2014]魔法森林 Time Limit: 30 Sec  Memory Limit: 512 MBSubmit: 363  Solved: 202[Submit][Status] ...

  2. BZOJ 3669: [Noi2014]魔法森林( LCT )

    排序搞掉一维, 然后就用LCT维护加边MST. O(NlogN) ------------------------------------------------------------------- ...

  3. bzoj 3669: [Noi2014]魔法森林

    bzoj 3669: [Noi2014]魔法森林 Description 为了得到书法大家的真传,小E同学下定决心去拜访住在魔法森林中的隐士.魔法森林可以被看成一个包含个N节点M条边的无向图,节点标号 ...

  4. BZOJ_3669_[Noi2014]魔法森林_LCT

    BZOJ_3669_[Noi2014]魔法森林_LCT Description 为了得到书法大家的真传,小E同学下定决心去拜访住在魔法森林中的隐士.魔法森林可以被看成一个包含个N节点M条边的无向图,节 ...

  5. bzoj 3669: [Noi2014]魔法森林 (LCT)

    链接:https://www.lydsy.com/JudgeOnline/problem.php?id=3669 题面: 3669: [Noi2014]魔法森林 Time Limit: 30 Sec  ...

  6. 「luogu2387」[NOI2014] 魔法森林

    「luogu2387」[NOI2014] 魔法森林 题目大意 \(n\) 个点 \(m\) 条边的无向图,每条边上有两个权值 \(a,b\),求从 \(1\) 节点到 \(n\) 节点 \(max\{ ...

  7. P2387 [NOI2014]魔法森林(LCT)

    P2387 [NOI2014]魔法森林 LCT边权维护经典题 咋维护呢?边化为点,边权变点权. 本题中我们把边对关键字A进行排序,动态维护关键字B的最小生成树 加边后出现环咋办? splay维护最大边 ...

  8. [NOI2014]魔法森林 LCT

    题面 [NOI2014]魔法森林 题解 一条路径的代价为路径上的\(max(a[i]) + max(b[i])\),因为一条边同时有$a[i], b[i]$2种权值,直接处理不好同时兼顾到,所以我们考 ...

  9. bzoj 3669: [Noi2014]魔法森林 -- 动点spfa

    3669: [Noi2014]魔法森林 Time Limit: 30 Sec  Memory Limit: 512 MB 动点spfa Description 为了得到书法大家的真传,小E同学下定决心 ...

随机推荐

  1. java多线程 join方法以及优先级方法

    /*join:当A线程执行到了B线程的.join()方法时,A就会等待.等B线程都执行完,A才会执行. join可以用来临时加入线程执行. 1.线程使用join方法,主线程就停下,等它执行完,那么如果 ...

  2. 07_Java8新增的Lambda表达式

    [Lambda表达式概述] Lambda表达式支持将代码块作为方法参数,Lambda表达式允许将使用简洁的代码来创建只有一个抽象方法的接口的实例.(这种接口称为函数式接口) [入门实例] packag ...

  3. 2017 google Round C APAC Test 题解

    题解参考网上的答案,以及我自己的想法. 主要参考网站:http://codeforces.com/blog/entry/47181,http://codeforces.com/blog/entry/4 ...

  4. Wix installer: suppressing the License Dialog

    Reference Link:  http://blog.robseder.com/2014/02/20/more-on-wix-and-suppressing-the-license-dialog/ ...

  5. 结构型模式——Bridge(未完成)

    1.意图 将抽象部分与它的实现部分分离,使它们都可以独立地变化.

  6. leetcode problem 37 -- Sudoku Solver

    解决数独 Write a program to solve a Sudoku puzzle by filling the empty cells. Empty cells are indicated ...

  7. Winform窗口弹出位置控制

    窗体的弹出位置可以由属性StartPosition来指定,默认值有: Manural 自定义,由属性Location指定: CenterScreen 屏幕中央: WindowsDefaultBound ...

  8. prefix和unprefix

    exports._esModule = true; exports.default = { prefix: function prefix(prop){ if (prop[0] === '-'){ v ...

  9. Sublime Text 3使用技巧总结--快捷键及常用插件

    1.Goto Anything(快速搜索) |--Ctrl+p 输入|--①文件名 |--②@+函数名 |--③:+数字 ->跳转到相应行 |--④#+变量名 2.多行游标 |--|--Alt+ ...

  10. MEF学习笔记

    之前公司里用到了一个叫MEF的东西,说来惭愧一直只管写代码却不曾理解MEF框架为何物,今天就来学习一下,这是一篇迟到了不知多久的博客. -------------------------------- ...