题意可以百度。
话说,这是一个很 YD 的最大流模型题。不过似乎可用 floyd+匈牙利 做。
最大流模板就不说了,主要说一下构图。(也就是这个题 YD 的地方)
大致方向是这样的:虚拟源点和汇点,所有插座与汇点连边,方向指向汇点,流量为 1 。所有用电器和源点连边,指向用电器,流量为 1 。然后可以转换插头的再连边,流量为 +∞ (因为他给出的是转换器的种类,个数不限)。
但是,YD 的地方是这里:有数据是用电器的插头的型号与插座都不一样,也就是图不连通。还有数据是有转换器的两个节点既不是用电器也不是插座,也就是需要为转换器另开节点。这样一来,总的节点数就是:m(用电器)+n(插座)+tot(为那种特殊的转换器新申请的节点)+2(源点和汇点)。
还有一个更 YD 的,就是,当最大流>用电器,就是说将这些用电器全插上之后插座还有富余,这时要输出 0 而不是负数。
代码(SueMiller):
program ACRush;
var n,m,mm:longint;
i,j,k,ii,jj,kk,ss,tt,tot:longint;
a,b,c:array[0..510]of string;
t:array[0..510,0..510]of longint;
q:array[0..3010]of longint;
num:array[0..510]of longint;
s,s1,s2:string;
ans:longint;
function min(a,b:longint):longint;
begin
if a<b then exit(a) else exit(b);
end;
function bfs:boolean;
var head,tail:longint;
i:longint;
begin
fillchar(num,sizeof(num),0);
head:=0;
tail:=1;
q[1]:=ss;
num[ss]:=1;
while head<tail do
begin
inc(head);
for i:=0 to n+m+tot+1 do
if t[q[head],i]>0 then
if num[i]=0 then
begin
num[i]:=num[q[head]]+1;
inc(tail);
q[tail]:=i;
end;
end;
if num[tt]=0 then exit(false) else exit(true);
end;
function dfs(now,flow:longint):longint;
var i,temp:longint;
begin
if now=tt then exit(flow);
for i:=0 to n+m+tot+1 do
if t[now,i]>0 then
if num[i]=num[now]+1 then
begin
temp:=dfs(i,min(flow,t[now,i]));
if temp>0 then
begin
dec(t[now,i],temp);
inc(t[i,now],temp);
exit(temp);
end;
end;
exit(0);
end;
begin
readln(n);
for i:=1 to n do
readln(a[i]);
readln(m);
for i:=1 to m do
begin
readln(s);
s1:=copy(s,pos(' ',s)+1,length(s)-pos(' ',s));
for j:=1 to n do
if a[j]=s1 then
begin
t[i,j+m]:=maxlongint>>2;
end;
b[i]:=s1;
end;
readln(mm);
for i:=1 to mm do
begin
readln(s);
s2:=copy(s,pos(' ',s)+1,length(s)-pos(' ',s));
s1:=copy(s,1,pos(' ',s)-1);
ii:=0;jj:=0;
for j:=1 to n+m+tot do
begin
if (j>m) and (j<=m+n) then
begin
if a[j-m]=s1 then ii:=j;
if a[j-m]=s2 then jj:=j;
end;
if j<=m then
begin
if b[j]=s1 then ii:=j;
if b[j]=s2 then jj:=j;
end;
if j>m+n then
begin
if c[j-m-n]=s1 then ii:=j;
if c[j-m-n]=s2 then jj:=j;
end;
if (ii>0) and (jj>0) then t[ii,jj]:=maxlongint>>2;
end;
if ii=0 then
begin
inc(tot);
c[tot]:=s1;
end;
if jj=0 then
begin
inc(tot);
c[tot]:=s2;
end;
if (ii=0) and (jj=0) then
t[m+n+tot-1,m+n+tot]:=maxlongint>>2;
end;
ss:=0;tt:=m+n+tot+1;
for i:=1 to m do
t[ss,i]:=1;
for i:=m+n+1 to m+n+tot do
t[ss,i]:=1;
for i:=m+1 to m+n do
t[i,tt]:=1;
ans:=0;
while bfs do
begin
kk:=dfs(ss,maxlongint>>2);
while kk>0 do
begin
inc(ans,kk);
kk:=dfs(ss,maxlongint>>2);
end;
end;
if ans>m then ans:=m;
writeln(m-ans);
end.