大意:最大匹配。
分析:网络流,连边,用一个原点和终点连接二分图两边。
设容量为1,求原点到终点的最大流。
(没有特殊判断的方案不管)
代码:
const
maxn=2003;
maxm=200003;
type
node=record
y,c,next,op:longint;
end;
var
e,n,m,s,t,ans,d,x,y,i:longint;
ls,dis,q,cur:array [0..maxn] of longint;
g:array [0..maxm*2] of node;
procedure add(u,v,c:longint);
begin
inc(e);
g[e].y:=v; g[e].c:=c; g[e].op:=e+1; g[e].next:=ls[u]; ls[u]:=e;
inc(e);
g[e].y:=u; g[e].c:=0; g[e].op:=e-1; g[e].next:=ls[v]; ls[v]:=e;
end;
function bfs:boolean;
var i,head,tail,tt,u:longint;
begin
for i:=s to t do
dis[i]:=0;
dis[s]:=1;
head:=0; tail:=1;
inc(tail);
q[tail]:=s;
while head<=tail do
begin
inc(head);
u:=q[head];
i:=ls[u];
while i>0 do
begin
if (g[i].c<>0) and (dis[g[i].y]=0) then
begin
dis[g[i].y]:=dis[u]+1;
if g[i].y=t then exit(true);
inc(tail);
q[tail]:=g[i].y;
end;
i:=g[i].next;
end;
end;
exit(false);
end;
function min(x,y:longint):longint;
begin
if x<y then exit(x)
else exit(y);
end;
function dfs(x,maxf:longint):longint;
var ret,i,f:longint;
begin
if (x=t) or (maxf=0) then exit(maxf);
ret:=0;
i:=cur[x];
while i>0 do
begin
if (g[i].c<>0) and (dis[g[i].y]=dis[x]+1) then
begin
f:=dfs(g[i].y,min(g[i].c,maxf));
dec(g[i].c,f);
inc(g[g[i].op].c,f);
ret:=ret+f;
if ret=maxf then break;
end;
i:=g[i].next;
end;
exit(ret);
end;
procedure dinic;
var i:longint;
begin
while bfs do
begin
for i:=s to t do
cur[i]:=ls[i];
ans:=ans+dfs(s,maxlongint);
end;
end;
begin
readln(n,d);
for i:=1 to n do
add(0,i,1);
for i:=n+1 to d do
add(i,d+1,1);
s:=0; t:=d+1;
repeat
readln(x,y);
if (x=-1) and (y=-1) then break;
add(x,y,1);
until 1=2;
dinic;
if ans<>0 then writeln(ans)
else writeln('No Solution');
end.