bzoj2285

完全是为了拼凑才出出来的吧
先分数规划求出到基地入口的最小安全系数
然后再最小点权覆盖集,只不过这里是带一定精度实数的流,其实是一样的

  1 const inf=100000000;
  2       eps=0.001;
  3 type way=record
  4        po,next,ti,sa:longint;
  5      end;
  6      node=record
  7        po,next:longint;
  8        flow:double;
  9      end;
 10 
 11 var w:array[0..100010] of way;
 12     e:array[0..100010] of node;
 13     d:array[0..800] of double;
 14     numh,h,pp,p,cur,pre:array[0..800] of longint;
 15     q:array[0..2000010] of longint;
 16     v:array[0..800] of boolean;
 17     i,t,n,m,m1,len,x,y,z,b:longint;
 18     ans:double;
 19 
 20 function min(a,b:double):double;
 21   begin
 22     if a>b then exit(b) else exit(a);
 23   end;
 24 
 25 procedure add(x,y,a,b:longint);
 26   begin
 27     inc(len);
 28     w[len].po:=y;
 29     w[len].ti:=a;
 30     w[len].sa:=b;
 31     w[len].next:=pp[x];
 32     pp[x]:=len;
 33   end;
 34 
 35 procedure ins(x,y:longint;f:double);
 36   begin
 37     inc(len);
 38     e[len].po:=y;
 39     e[len].flow:=f;
 40     e[len].next:=p[x];
 41     p[x]:=len;
 42   end;
 43 
 44 function check(t:longint;m:double):boolean;
 45   var x,y,f,r,i:longint;
 46   begin
 47     for i:=1 to n do
 48       d[i]:=inf;
 49     d[n]:=0;
 50     fillchar(v,sizeof(v),false);
 51     f:=1;
 52     r:=1;
 53     q[1]:=n;
 54     while f<=r do
 55     begin
 56       x:=q[f];
 57       v[x]:=false;
 58       i:=pp[x];
 59       while i<>0 do
 60       begin
 61         y:=w[i].po;
 62         if d[y]>d[x]+w[i].ti-m*w[i].sa then
 63         begin
 64           d[y]:=d[x]+w[i].ti-m*w[i].sa;
 65           if (y=t) and (d[y]<=0) then exit(true);
 66           if not v[y] then
 67           begin
 68             v[y]:=true;
 69             inc(r);
 70             q[r]:=y;
 71           end;
 72         end;
 73         i:=w[i].next;
 74       end;
 75       inc(f);
 76     end;
 77     if d[t]<=0 then exit(true) else exit(false);
 78   end;
 79 
 80 function calc(x:longint):double;
 81   var l,r,m:double;
 82   begin
 83     l:=0;
 84     r:=10;
 85     if not check(x,10) then exit(inf);
 86     while r-l>eps do
 87     begin
 88       m:=(l+r)/2;
 89       if check(x,m) then r:=m else l:=m;
 90     end;
 91     exit(r);
 92   end;
 93 
 94 procedure sap;
 95   var u,i,j,tmp,q:longint;
 96       neck:double;
 97   begin
 98     u:=0;
 99     for i:=0 to t do
100       cur[i]:=p[i];
101     numh[0]:=t+1;
102     neck:=inf;
103     while h[0]<t+1 do
104     begin
105       d[u]:=neck;
106       i:=cur[u];
107       while i<>-1 do
108       begin
109         j:=e[i].po;
110         if (e[i].flow>0) and (h[u]=h[j]+1) then
111         begin
112           pre[j]:=u;
113           cur[u]:=i;
114           neck:=min(neck,e[i].flow);
115           u:=j;
116           if u=t then
117           begin
118             ans:=ans+neck;
119             if ans>inf then exit;
120             while u<>0 do
121             begin
122               u:=pre[u];
123               j:=cur[u];
124               e[j].flow:=e[j].flow-neck;
125               e[j xor 1].flow:=e[j xor 1].flow+neck;
126             end;
127             neck:=inf;
128           end;
129           break;
130         end;
131         i:=e[i].next;
132       end;
133       if i=-1 then
134       begin
135         dec(numh[h[u]]);
136         if numh[h[u]]=0 then exit;
137         tmp:=t;
138         q:=-1;
139         i:=p[u];
140         while i<>-1 do
141         begin
142           j:=e[i].po;
143           if e[i].flow>0 then
144             if tmp>h[j] then
145             begin
146               tmp:=h[j];
147               q:=i;
148             end;
149           i:=e[i].next;
150         end;
151         h[u]:=tmp+1;
152         inc(numh[h[u]]);
153         cur[u]:=q;
154         if u<>0 then
155         begin
156           u:=pre[u];
157           neck:=d[u];
158         end;
159       end;
160     end;
161   end;
162 
163 begin
164   readln(n,m);
165   for i:=1 to m do
166   begin
167     readln(x,y,z,b);
168     add(x,y,z,b);
169   end;
170   len:=-1;
171   fillchar(p,sizeof(p),255);
172   readln(m1,t);
173   inc(t);
174   for i:=1 to t-1 do
175     if i mod 2=0 then
176     begin
177       ins(i,t,calc(i));
178       ins(t,i,0);
179     end
180     else begin
181       ins(0,i,calc(i));
182       ins(i,0,0);
183     end;
184 
185   for i:=1 to m1 do
186   begin
187     readln(x,y);
188     ins(x,y,inf);
189     ins(y,x,0);
190   end;
191   sap;
192   if ans>inf then writeln(-1)
193   else writeln(ans:0:1);
194 end.
View Code
原文地址:https://www.cnblogs.com/phile/p/4472980.html