裸模板,UOJ上有模板题,可以刷一刷
program bzoj;
var
ans,x,y,t,w,i,n,m,tot:longint;
g:array[0..1000,0..1000]of boolean;
next1,mark,line,vis,match,head,a,next,belong:array[0..100000]of longint;
procedure add(x,y:longint);
begin
inc(tot);
next1[tot]:=head[x];
head[x]:=tot;
a[tot]:=y;
inc(tot);
next1[tot]:=head[y];
head[y]:=tot;
a[tot]:=x;
end;
function findb(x:longint):longint;
begin
if belong[x]=x
then exit(x)
else
begin
belong[x]:=findb(belong[x]);
exit(belong[x]);
end;
end;
function lca(x,y:longint):longint;
var
t,temp:longint;
begin
t:=1;
while true do
begin
if x<>-1
then
begin
x:=findb(x);
if vis[x]=1
then exit(x);
vis[x]:=1;
if match[x]<>-1
then x:=next[match[x]]
else x:=-1;
end;
temp:=x;
x:=y;
y:=temp;
end;
end;
procedure unit1(x,y:longint);
begin
if (findb(x)<>findb(y))
then belong[findb(x)]:=findb(y);
end;
procedure group(x,p:longint);
var
a1,a2:longint;
begin
while x<>p do
begin
a1:=match[x];
a2:=next[a1];
if findb(a2)<>p
then next[a2]:=a1;
if mark[a1]=2
then
begin
inc(w);
line[w]:=a1;
mark[a1]:=1;
end;
if mark[a2]=2
then
begin
inc(w);
line[w]:=a2;
mark[a2]:=2;
end;
unit1(x,a1);
unit1(a1,a2);
x:=a2;
end;
end;
procedure aug(s:longint);
var
i,x,m,temp,u,v,mv:longint;
begin
for i:=0 to n do
begin
next[i]:=-1;
belong[i]:=i;
mark[i]:=0;
vis[i]:=0;
end;
mark[s]:=1;
t:=1;
w:=1;
line[w]:=s;
while (t<=w)and(match[s]=-1) do
begin
x:=line[t];
m:=head[x];
while m<>-1 do
begin
if (match[x]<>a[m])and(findb(x)<>findb(a[m]))and(mark[a[m]]<>2)
then
begin
if mark[a[m]]=1
then
begin
temp:=lca(x,a[m]);
if findb(x)<>temp
then next[x]:=a[m];
if findb(a[m])<>temp
then next[a[m]]:=temp;
group(x,temp);
group(a[m],temp);
end
else
begin
if match[a[m]]=-1
then
begin
next[a[m]]:=x;
u:=a[m];
while u<>-1 do
begin
v:=next[u];
mv:=match[v];
match[v]:=u;
match[u]:=v;
u:=mv;
end;
break;
end
else
begin
next[a[m]]:=x;
inc(w);
line[w]:=match[a[m]];
mark[line[w]]:=1;
mark[a[m]]:=2;
end;
end;
end;
m:=next1[m];
end;
end;
end;
begin
assign(input,'bzoj.in');
assign(output,'bzoj.out');
reset(input);
rewrite(output);
read(n,m);
fillchar(g,sizeof(g),false);
for i:=0 to n do
head[i]:=-1;
for i:=1 to m do
begin
read(x,y);
dec(x);
dec(y);
if (x<>y)and(not g[x,y])
then
begin
add(x,y);
g[x,y]:=true;
g[y,x]:=true;
end;
end;
dec(n);
for i:=0 to n do
begin
match[i]:=-1;
end;
for i:=0 to n do
begin
if match[i]=-1
then aug(i);
end;
for i:=0 to n do
begin
if match[i]<>-1
then inc(ans);
end;
writeln(ans);
close(input);
close(output);
end.
UOJ 一般图的最大匹配(带花树算法模板)
最新推荐文章于 2020-07-24 16:50:22 发布