【题意】
某女友n个工作,每个工作每周只有限定的时间能做,起码要做d天,要在w周内完成,问是否能完成所有任务
【输入】
第一行一个t表示多少组数据
每组数据第一行一个数字n
接下来n行9个数字描述一件工作,前七个表示周一到周日是否可以去工作,之后是d、w
【输出】
对于每组数据输出"Yes"或"No"表示是否能完成所有任务
最大流问题
w周里每一天都抽象成一个点,从源向其连一条流量为1的边,对于每个工作抽象成一个点,向汇连流量d的边,如果某天可以做某工作,那么连一条流量为1的边
求是否最大流等于d的总和即可
program poj1698;
var
max,d,w,sum,tot,t,n,i,j,k:longint;
could:array [1..7] of longint;
last,dl,root:array [0..501] of longint;
yes:array [0..501] of boolean;
point,next,flow:array [0..30001] of longint;
function anti (now:longint):longint;inline;
begin
if now and 1 = 1 then exit(now+1)
else exit(now-1);
end;
procedure connect (u,v,f:longint);inline;
begin
inc(tot);
point[tot]:=v;
flow[tot]:=f;
next[tot]:=root[u];
root[u]:=tot;
end;
function maxflow :longint;
begin
maxflow:=0;
repeat
fillchar(yes,sizeof(yes),false);
i:=0;
tot:=0;
dl[0]:=0;
yes[0]:=true;
while i<=tot do
begin
if yes[350+n+1] then break;
k:=root[dl[i]];
while k<>0 do
begin
if (not yes[point[k]])and(flow[k]>0) then
begin
yes[point[k]]:=true;
inc(tot);
dl[tot]:=point[k];
last[point[k]]:=k;
end;
k:=next[k];
end;
inc(i);
end;
if not yes[350+n+1] then break;
max:=maxlongint;
i:=350+n+1;
while i<>0 do
begin
if flow[last[i]]<max then max:=flow[last[i]];
i:=point[anti(last[i])];
end;
inc(maxflow,max);
i:=350+n+1;
while i<>0 do
begin
flow[last[i]]:=flow[last[i]]-max;
flow[anti(last[i])]:=flow[anti(last[i])]+max;
i:=point[anti(last[i])];
end;
until false;
end;
begin
read(t);
while t>0 do
begin
dec(t);
fillchar(root,sizeof(root),0);
tot:=0;
for i:=1 to 50 do
for j:=1 to 7 do
begin
connect(0,(i-1)*7+j,1);
connect((i-1)*7+j,0,0);
end;
sum:=0;
read(n);
for i:=1 to n do
begin
for j:=1 to 7 do
read(could[j]);
read(d,w);
sum:=sum+d;
connect(350+i,350+n+1,d);
connect(350+n+1,350+i,0);
for j:=1 to 7 do
if could[j]=1 then
for k:=1 to w do
begin
connect((k-1)*7+j,350+i,1);
connect(350+i,(k-1)*7+j,0);
end;
end;
if maxflow=sum then writeln('Yes')
else writeln('No');
end;
end.