比赛 20120708 评测结果 WWWWWWWWWW
题目名称 最小最大生成树 最终得分 0
用户昵称 isabella 运行时间 0.740 s
代码语言 Pascal 内存使用 14.78 MiB
提交时间 2012-07-08 11:57:02
显示代码纯文本
var
 x,y,w:array[1..200002]of longint;
 mx,my,mw,name,hh,cry:array[1..400002]of longint;
 p,ex,ee:array[1..400002]of boolean;
 pp:array[1..200002]of boolean;
 po:array[1..200002,1..2]of longint;
 s,t,fa,num:array[1..20002]of longint;
 n,m,i,j,k,l,temp,mid,midk,u,v,tot,mitre,matre,ans1,ans,b1,ans2,ansk:longint;
 flag:boolean;

 function max(a,b:longint):longint;
 begin if a>b then exit(a) else exit(b);end;
 function min(a,b:longint):longint;
 begin if a<b then exit(a) else exit(b);end;

 procedure sort1(l,r:longint);
  var i,j:longint;
  begin
   i:=l;j:=r;mid:=w[(i+j)div 2];
   repeat
    while w[i]<mid do inc(i);
    while w[j]>mid do dec(j);
    if i<=j then
     begin
      temp:=w[i];w[i]:=w[j];w[j]:=temp;
      temp:=x[i];x[i]:=x[j];x[j]:=temp;
      temp:=y[i];y[i]:=y[j];y[j]:=temp;
      temp:=hh[i];hh[i]:=hh[j];hh[j]:=temp;
      temp:=po[i,1];po[i,1]:=po[j,1];po[j,1]:=temp;
      temp:=po[i,2];po[i,2]:=po[j,2];po[j,2]:=temp;
      inc(i);dec(j);
     end;
   until i>j;
   if i<r then sort1(i,r);
   if l<j then sort1(l,j);
  end;
 procedure sort2(l,r:longint);
  var i,j:longint;
  begin
   i:=l;j:=r;mid:=x[(i+j)div 2];
   midk:=w[(i+j)div 2];
   repeat
    while (x[i]<mid)or((x[i]=mid)and(w[i]<midk)) do inc(i);
    while (x[j]>mid)or((x[j]=mid)and(w[j]>midk)) do dec(j);
    if i<=j then
     begin
      temp:=mw[i];mw[i]:=mw[j];mw[j]:=temp;
      temp:=mx[i];mx[i]:=mx[j];mx[j]:=temp;
      temp:=my[i];my[i]:=my[j];my[j]:=temp;
      temp:=name[i];name[i]:=name[j];name[j]:=temp;
      inc(i);dec(j);
     end;
   until i>j;
   if i<r then sort2(i,r);
   if l<j then sort2(l,j);
  end;

 function father(x:longint):longint;
  begin
   if fa[x]=x then exit(x);
   fa[x]:=father(fa[x]);
   exit(fa[x]);
  end;

 procedure hebing(x,y:longint);
  var i,j:longint;
  begin
   i:=father(x);j:=father(y);
   fa[i]:=j;
  end;

 procedure first;
  begin
   fillchar(p,sizeof(p),0);
   fillchar(pp,sizeof(pp),0);
   fillchar(ex,sizeof(ex),0);
   fillchar(ee,sizeof(ee),0);
   readln(n,m);
   for i:=1 to m do
    begin
     read(x[i],y[i],w[i]);
     hh[i]:=i;
     mx[i]:=x[i];my[i]:=y[i];mw[i]:=w[i];
     mx[i+m]:=y[i];my[i+m]:=x[i];mw[i+m]:=w[i];
     name[i]:=i;name[i+m]:=i+m;
     po[i,1]:=i;po[i,2]:=i+m;
    end;

   readln(u,v,l);
   for i:=1 to m do
    if ((x[i]=u)and(y[i]=v))or((x[i]=v)and(y[i]=u))then
     begin
      ans:=1;w[i]:=l;b1:=i;
      mw[i]:=l;mw[i+m]:=l;
      break;
     end;

   if ans=0 then
    begin
     inc(m);x[m]:=u;y[m]:=v;w[m]:=l;b1:=m;hh[m]:=m;
     i:=m;
     mx[i]:=x[i];my[i]:=y[i];mw[i]:=w[i];
     mx[i+m]:=y[i];my[i+m]:=x[i];mw[i+m]:=w[i];
     name[i]:=i;name[i+m]:=i+m;
     po[i,1]:=i;po[i,2]:=i+m;
    end;
  end;

 procedure make2;
  var i,j,tt,tk:longint;
  begin
    sort1(1,m);
    for i:=1 to m do cry[hh[i]]:=i;

    sort2(1,m*2);
    for i:=1 to m*2 do
     begin
      tt:=name[i]mod m;if tt=0 then tt:=m;
      tk:=name[i]div m;if tk=2 then tk:=1;
      po[cry[tt],tk+1]:=i;
     end;

    j:=1;
    for i:=1 to n do
     begin
      s[i]:=j;
      while mx[j]=i do inc(j);
      t[i]:=j-1;
     end;
    for i:=1 to n do
     for j:=s[i] to t[i] do
      if mw[j]>l then begin num[i]:=j-s[i];break;end;

  end;

 procedure dfs(a,b:longint);
  var i,tt:longint;
  begin
   if a=b then begin flag:=true;exit;end;
   for i:=s[a]to t[a] do
    if p[i]=true then
     begin
      tt:=ans1;ans1:=max(ans1,mw[i]);
      dfs(my[i],b);
      if flag then exit;
      ans1:=tt;
     end;
  end;

 procedure dfs2(a,b:longint);
  var i,tt:longint;
  begin
   if a=b then begin flag:=true;exit;end;
   for i:=s[a]to t[a] do
    if (p[i]=true)and(ex[i]=false) then
     begin
      tt:=ans1;ans1:=min(ans1,mw[i]);
      dfs(my[i],b);
      if flag then exit;
      ans1:=tt;
     end;
  end;

 procedure find(k:longint);
  var i:longint;
  begin
   ans1:=0;
   flag:=false;
   dfs(x[k],y[k]);
   if ans1=w[k] then begin pp[k]:=true;p[po[k,1]]:=true;p[po[k,2]]:=true;end;
  end;

 procedure find2(k:longint);
  var i:longint;
  begin
   ans1:=maxlongint;
   flag:=false;
   dfs2(x[k],y[k]);
   if ans1=w[k] then begin pp[k]:=true;p[po[k,1]]:=true;p[po[k,2]]:=true;end;
  end;


 procedure kruscal;
  begin
   tot:=1;mitre:=0;
   for i:=1 to n do fa[i]:=i;
   for i:=1 to m do
    begin
     if father(x[i])<>father(y[i]) then
       begin
        inc(mitre,w[i]);hebing(x[i],y[i]);inc(tot);
        p[po[i,1]]:=true;p[po[i,2]]:=true;
        pp[i]:=true;
       end;
     if tot=n then break;
    end;

   for i:=1 to m do
    if pp[i]=false then find(i);

  end;

 procedure sou(a,b,tt,tk:longint);
  var i,j,jj:longint;
  begin
   if a=b then
    begin
     if tt<ans2 then begin ans2:=tt;ansk:=tk;end;
     exit;
    end;

   for i:=s[a]to t[a] do
    if p[i] then
     begin
      if num[mx[i]]<tt then sou(my[i],b,num[mx[i]],mx[i])
       else sou(my[i],b,tt,tk);
     end;
  end;

 procedure sou2(a,b,tt,tk:longint);
  var i,j,jj:longint;
  begin
   if a=b then
    begin
     if tt<ans2 then begin ans2:=tt;ansk:=tk;end;
     exit;
    end;

   for i:=s[a]to t[a] do
    if (p[i])and(ex[i]=false) then
     begin
      if (t[a]-s[a]+1-num[mx[i]])<tt then sou(my[i],b,t[a]-s[a]+1-num[mx[i]],mx[i])
       else sou(my[i],b,tt,tk);
     end;
  end;
begin
assign(input,'mstmn.in');reset(input);
assign(output,'mstmn.out');rewrite(output);
 first;
 make2;
 kruscal;

 if pp[cry[b1]]=false then
 begin
  ans2:=maxlongint;ansk:=u;
  sou(u,v,ans2,ansk);
  if ans2<200000 then begin
   ans:=ans+ans2;

  for i:=s[ansk]to s[ansk]+ans2-1 do
   begin ex[i]:=true;ee[cry[name[i]mod m]]:=true;end;  end;
 end;

 fillchar(pp,sizeof(pp),0);
 fillchar(p,sizeof(p),0);

 tot:=1;for i:=1 to n do fa[i]:=i;
 for i:=m downto 1 do
  if ee[i]=false then
   begin
    if father(x[i])<>father(y[i]) then
       begin
        hebing(x[i],y[i]);inc(tot);
        p[po[i,1]]:=true;p[po[i,2]]:=true;
        pp[i]:=true;
       end;
     if tot=n then break;
   end;

   for i:=1 to m do
    if (pp[i]=false)and(ee[i]=false) then find2(i);

 if pp[cry[b1]]=false then
 begin
  ans2:=maxlongint;ansk:=u;
  sou2(u,v,ans2,ansk);
  ans:=ans+ans2;
 end;

 writeln(ans);
close(input);close(output);
end.