【ZJOI2017 Round1练习&&BZOJ5353】D7T2 guess(费用流)
题意:
思路:
1 var head,vet,next,len1,len2,x,y,p1,p2,dis,a,b,fan:array[1..100000]of longint; 2 pre:array[1..100000,1..2]of longint; 3 inq:array[1..100000]of boolean; 4 q:array[0..1000]of longint; 5 n,m,i,j,ans,tot,source,src,s,t1,t2:longint; 6 7 function min(x,y:longint):longint; 8 begin 9 if x<y then exit(x); 10 exit(y); 11 end; 12 13 procedure add(a,b,c,d:longint); 14 begin 15 inc(tot); 16 next[tot]:=head[a]; 17 vet[tot]:=b; 18 len1[tot]:=c; 19 len2[tot]:=d; 20 head[a]:=tot; 21 22 inc(tot); 23 next[tot]:=head[b]; 24 vet[tot]:=a; 25 len1[tot]:=0; 26 len2[tot]:=-d; 27 head[b]:=tot; 28 end; 29 30 function find(x,y:longint):boolean; 31 var i:longint; 32 begin 33 for i:=1 to n do 34 if (x=a[i])and(y=b[i]) then exit(true); 35 exit(false); 36 end; 37 38 function spfa:boolean; 39 var u,e,v,i,t,w,t1,w1:longint; 40 begin 41 for i:=1 to s do 42 begin 43 dis[i]:=maxlongint>>1; 44 inq[i]:=false; 45 end; 46 t:=0; w:=1; t1:=0; w1:=1; q[1]:=source; dis[source]:=0; inq[source]:=true; 47 while t<w do 48 begin 49 inc(t); inc(t1); 50 if t1=1000 then t1:=0; 51 u:=q[t1]; inq[u]:=false; 52 e:=head[u]; 53 while e<>0 do 54 begin 55 v:=vet[e]; 56 if (len1[e]>0)and(dis[u]+len2[e]<dis[v]) then 57 begin 58 pre[v,1]:=u; 59 pre[v,2]:=e; 60 dis[v]:=dis[u]+len2[e]; 61 if not inq[v] then 62 begin 63 inc(w); inc(w1); 64 if w1=1000 then w1:=0; 65 q[w1]:=v; inq[v]:=true; 66 end; 67 end; 68 e:=next[e]; 69 end; 70 end; 71 if dis[src]=maxlongint>>1 then exit(false); 72 exit(true); 73 end; 74 75 procedure mcf; 76 var k,e,t:longint; 77 begin 78 k:=src; t:=maxlongint; 79 while k<>source do 80 begin 81 t:=min(t,len1[pre[k,2]]); 82 k:=pre[k,1]; 83 end; 84 k:=src; 85 while k<>source do 86 begin 87 e:=pre[k,2]; 88 len1[e]:=len1[e]-t; 89 len1[fan[e]]:=len1[fan[e]]+t; 90 ans:=ans+t*len2[e]; 91 k:=pre[k,1]; 92 end; 93 end; 94 95 begin 96 assign(input,'guess.in'); reset(input); 97 assign(output,'guess.out'); rewrite(output); 98 readln(n); 99 for i:=1 to 100000 do 100 if i and 1=1 then fan[i]:=i+1 101 else fan[i]:=i-1; 102 for i:=1 to n do 103 begin 104 readln(a[i],b[i]); 105 inc(x[a[i]]); inc(y[b[i]]); 106 end; 107 for i:=1 to 100000 do 108 if x[i]>0 then inc(s); 109 for i:=1 to 100000 do 110 if y[i]>0 then inc(s); 111 source:=s+1; src:=s+2; s:=s+2; 112 for i:=1 to 100000 do 113 if x[i]>0 then 114 begin 115 inc(t1); p1[t1]:=i; 116 add(source,t1,x[i],0); 117 end; 118 for i:=1 to 100000 do 119 if y[i]>0 then 120 begin 121 inc(t2); p2[t2]:=i; 122 add(t1+t2,src,y[i],0); 123 end; 124 for i:=1 to t1 do 125 for j:=1 to t2 do 126 if find(p1[i],p2[j]) then add(i,j+t1,1,1) 127 else add(i,j+t1,1,0); 128 while spfa do mcf; 129 writeln(ans); 130 close(input); 131 close(output); 132 end.
null