poj 1698 Alice's Chance 二分图最大匹配

题目大意:爱丽丝要拍电影,有n部电影,规定爱丽丝每部电影在每个礼拜只有固定的几天可以拍电影,只可以拍前面w个礼拜,并且这部电影要拍d天,问爱丽丝能不能拍完所有的电影
第一行代表有多少组数据
对于每组数据第一行代表有n部电影

接下来2到n+1行,每行代表一个电影,每行9个数,前面7个数,1代表拍,0代表不拍,第8个数代表要拍几天,第9个数代表有几个礼拜时间拍。

分析:先把天数和电影建二分图,然后把点0设为源点,把点371设为汇点,再进行网络流。若最大流等于所有电影需要拍的天数加起来,则Yes否则No。

代码:

var
  t,l,i,j,k,n,tot,ans,x,y:longint;
  fa:array[0..371] of longint;
  a:array[0..371,0..371] of longint;
  d:array[1..7] of longint;

function find(x:longint):boolean;
var
  i:longint;
begin
  if x=371 then exit(true);
  find:=false;
  for i:=1 to 371 do
    if (a[x,i]>0)and(fa[i]=-1) then
    begin
      fa[i]:=x;
      if find(i) then exit(true);
    end;
end;

procedure add;
var
  i,min:longint;
begin
  i:=371;
  min:=maxlongint;
  while i>0 do
  begin
    dec(a[fa[i],i]);
    inc(a[i,fa[i]]);
    i:=fa[i];
  end;
  inc(ans);
end;

procedure main;
var
  i:longint;
begin
  for i:=0 to 371 do
    fa[i]:=-1;
  fa[0]:=0;
  while find(0) do
  begin
    add;
    for i:=0 to 371 do
      fa[i]:=-1;
    fa[0]:=0;
  end;
end;

begin
  readln(t);
  for l:=1 to t do
  begin
    readln(n);
    fillchar(a,sizeof(a),0);
    tot:=0;
    for i:=1 to n do
    begin
      for j:=1 to 7 do
        read(d[j]);
      readln(x,y);
      tot:=tot+x;
      for j:=0 to y-1 do
        for k:=1 to 7 do
          if d[k]=1 then
            a[j*7+k,350+i]:=1;
      a[350+i,371]:=x;
    end;
    for i:=1 to 350 do
      a[0,i]:=1;
    ans:=0;
    main;
    if ans=tot
      then writeln('Yes')
      else writeln('No');
  end;
end.


你可能感兴趣的:(poj 1698 Alice's Chance 二分图最大匹配)