对于新加入的边,必须要既可能在最小生成树上也可能在最大生成树上
我们先对于最小生成树考虑
根据kruskal的理论,不难发现,u--v 长度为L的边可能出现在最小生成树上
就是说删边剩下的比L小的边一定不能使u,v连通,
因此问题就转化为求u,v两点的最小割了
最大生成树同理,最后答案是两个加起来

  1 const inf=1000007;
  2 type node=record
  3        point,next,flow:longint;
  4      end;
  5 
  6 var edge:array[0..800010] of node;
  7     cur,p,h,numh,pre,d:array[0..20010] of longint;
  8     x,y,z:array[0..200010] of longint;
  9     i,len,u,v,l,ans,n,m:longint;
 10 
 11 function min(a,b:longint):longint;
 12   begin
 13     if a>b then exit(b) else exit(a);
 14   end;
 15 
 16 procedure add(x,y,z:longint);
 17   begin
 18     inc(len);
 19     edge[len].point:=y;
 20     edge[len].flow:=z;
 21     edge[len].next:=p[x];
 22     p[x]:=len;
 23   end;
 24 
 25 function sap(s,t:longint):longint;
 26   var u,i,j,q,tmp,neck:longint;
 27   begin
 28     for i:=1 to n do
 29       cur[i]:=i;
 30     fillchar(numh,sizeof(numh),0);
 31     fillchar(h,sizeof(h),0);
 32     u:=s;
 33     h[s]:=0;
 34     numh[0]:=n;
 35     neck:=inf;
 36     sap:=0;
 37     while h[s]<n do
 38     begin
 39       d[u]:=neck;
 40       i:=cur[u];
 41       while i<>-1 do
 42       begin
 43         j:=edge[i].point;
 44         if (edge[i].flow>0) and (h[u]=h[j]+1) then
 45         begin
 46           cur[u]:=i;
 47           pre[j]:=u;
 48           neck:=min(neck,edge[i].flow);
 49           u:=j;
 50           if u=t then
 51           begin
 52             sap:=sap+neck;
 53             while u<>s do
 54             begin
 55               u:=pre[u];
 56               j:=cur[u];
 57               dec(edge[j].flow,neck);
 58               inc(edge[j xor 1].flow,neck);
 59             end;
 60             neck:=inf;
 61           end;
 62           break;
 63         end;
 64         i:=edge[i].next;
 65       end;
 66       if i=-1 then
 67       begin
 68         dec(numh[h[u]]);
 69         if numh[h[u]]=0 then exit;
 70         q:=-1;
 71         tmp:=n;
 72         i:=p[u];
 73         while i<>-1 do
 74         begin
 75           j:=edge[i].point;
 76           if (edge[i].flow>0) then
 77             if h[j]<tmp then
 78             begin
 79               tmp:=h[j];
 80               q:=i;
 81             end;
 82           i:=edge[i].next;
 83         end;
 84         cur[u]:=q;
 85         h[u]:=tmp+1;
 86         inc(numh[h[u]]);
 87         if u<>s then
 88         begin
 89           u:=pre[u];
 90           neck:=d[u];
 91         end;
 92       end;
 93     end;
 94   end;
 95 
 96 begin
 97   readln(n,m);
 98   for i:=1 to m do
 99     readln(x[i],y[i],z[i]);
100   readln(u,v,l);
101   fillchar(p,sizeof(p),255);
102   len:=-1;
103   for i:=1 to m do
104     if z[i]>l then
105     begin
106       add(x[i],y[i],1);
107       add(y[i],x[i],0);
108       add(y[i],x[i],1);
109       add(x[i],y[i],0);
110     end;
111   ans:=sap(u,v);
112 
113   fillchar(p,sizeof(p),255);
114   len:=-1;
115   for i:=1 to m do
116     if z[i]<l then
117     begin
118       add(x[i],y[i],1);
119       add(y[i],x[i],0);
120       add(y[i],x[i],1);
121       add(x[i],y[i],0);
122     end;
123   ans:=ans+sap(u,v);
124   writeln(ans);
125 end.
View Code

 

posted on 2014-12-19 22:21  acphile  阅读(201)  评论(0编辑  收藏  举报