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