poj1698

【题意】

某女友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.


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值