bzoj1937

这道题没弄明白

初始模型很好想,是用到了最小生成树的性质

加入非树边后树上形成的环,非树边一定大于等于任意树边

然后考虑树边一定是缩小,非树边一定是增大

有di+wi>=dj-wj wi+wj>=dj-di(j是加入i形成的环上的边)

然后不知道为什么求∑wi最小就是跑最大费用可行流

求神犇指教

  1 type node=record
  2        po,next,cost,flow:longint;
  3      end;
  4 
  5 var e:array[0..2000010] of node;
  6     v,f:array[0..810] of boolean;
  7     a:array[0..60,0..60] of longint;
  8     d,pre,cur,w,p:array[0..810] of longint;
  9     q:array[0..2000010] of longint;
 10     x,y,len,i,j,n,m,t,k:longint;
 11 
 12 procedure add(x,y,f,c:longint);
 13   begin
 14     inc(len);
 15     e[len].po:=y;
 16     e[len].next:=p[x];
 17     e[len].cost:=c;
 18     e[len].flow:=f;
 19     p[x]:=len;
 20   end;
 21 
 22 procedure build(x,y,f,c:longint);
 23   begin
 24     add(x,y,f,c);
 25     add(y,x,0,-c);
 26   end;
 27 
 28 function dfs(x:longint):boolean;
 29   var i:longint;
 30   begin
 31     f[x]:=true;
 32     if x=j then
 33     begin
 34       q[0]:=-1;
 35       exit;
 36     end;
 37     for i:=1 to n do
 38       if not f[i] and v[a[x,i]] then
 39       begin
 40         inc(t);
 41         q[t]:=a[x,i];
 42         dfs(i);
 43         if q[0]=-1 then exit;
 44         q[t]:=0;
 45         dec(t);
 46       end;
 47   end;
 48 
 49 function spfa:boolean;
 50   var f,r,y,i,j,x:longint;
 51   begin
 52     f:=1;
 53     r:=1;
 54     q[1]:=0;
 55     d[0]:=0;
 56     for i:=1 to t do
 57       d[i]:=-1000007;
 58     fillchar(v,sizeof(v),false);
 59     while f<=r do
 60     begin
 61       x:=q[f];
 62       v[x]:=false;
 63       i:=p[x];
 64       while i<>-1 do
 65       begin
 66         y:=e[i].po;
 67         if e[i].flow>0 then
 68           if d[y]<d[x]+e[i].cost then
 69           begin
 70             d[y]:=d[x]+e[i].cost;
 71             pre[y]:=x;
 72             cur[y]:=i;
 73             if not v[y] then
 74             begin
 75               v[y]:=true;
 76               inc(r);
 77               q[r]:=y;
 78             end;
 79           end;
 80         i:=e[i].next;
 81       end;
 82       inc(f);
 83     end;
 84     if d[t]>=0 then exit(true) else exit(false);
 85   end;
 86 
 87 function maxcost:longint;
 88   var i,j:longint;
 89   begin
 90     maxcost:=0;
 91     while spfa do
 92     begin
 93       i:=t;
 94       while i<>0 do
 95       begin
 96         j:=cur[i];
 97         dec(e[j].flow);
 98         inc(e[j xor 1].flow);
 99         i:=pre[i];
100       end;
101       maxcost:=maxcost+d[t];
102     end;
103   end;
104 
105 begin
106   len:=-1;
107   fillchar(p,sizeof(p),255);
108   readln(n,m);
109   for i:=1 to m do
110   begin
111     readln(x,y,w[i]);
112     a[x,y]:=i;
113     a[y,x]:=i;
114   end;
115   for i:=1 to n-1 do
116   begin
117     readln(x,y);
118     k:=a[x,y];
119     v[k]:=true;
120     build(0,k,1,0);
121   end;
122   for i:=1 to n do
123     for j:=i+1 to n do
124       if (a[i,j]>0) and not v[a[i,j]] then
125       begin
126         build(a[i,j],m+1,1,0);
127         fillchar(f,sizeof(f),false);
128         t:=0; q[0]:=0;
129         dfs(i);
130         for k:=1 to t do
131           if w[q[k]]>w[a[i,j]] then build(q[k],a[i,j],1,w[q[k]]-w[a[i,j]]);
132       end;
133   t:=m+1;
134   writeln(maxcost);
135 end.
View Code
原文地址:https://www.cnblogs.com/phile/p/4490724.html