【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.
原文地址:https://www.cnblogs.com/myx12345/p/6530316.html