poj 2584 T-Shirt Gumbo 最大匹配

题意:现在要将5种型号的衣服分发给xn个参赛者,然后给出每个参赛者所需要的衣服的尺码的大小范围,在该尺码范围内的衣服该选手可以接受,再给出这5种型号衣服各自的数量,问是否存在一种分配方案使得每个选手都能够拿到自己尺码范围内的衣服. 

分析:先以选手和T恤建立一个二分图,每个选手和每件T恤都为一个顶点,然后把每个选手能穿T恤的范围和对应的所有T恤连边,再进行最大匹配,最后比较一下即可。

下面附程序:

var
  s:char;
  i,j,n,m,ans,x:longint;
  link:array[1..100] of longint;
  w:array[1..100,1..2] of longint; 
  num:array[1..100,1..2] of longint;
  v:array[1..100] of boolean;
  a:array[1..100,1..100] of boolean;

function find(x:longint):boolean;
var
  p,i:longint;
begin
  find:=false;
  for i:=1 to m do
    if (v[i])and(a[x,i]) then
    begin
      v[i]:=false;
      p:=link[i];
      link[i]:=x;
      if (p=0)or(find(p)) then exit(true);
      link[i]:=p;
    end;
end;

begin
  read(s);
  while s<>'E' do
  begin
    while s<>' ' do read(s);
    readln(n);
    for i:=1 to n do
    begin
      read(s);
      case s of
        'S':w[i,1]:=1;
        'M':w[i,1]:=2;
        'L':w[i,1]:=3;
        'X':w[i,1]:=4;
        'T':w[i,1]:=5;
      end;
      read(s);
      case s of
        'S':w[i,2]:=1;
        'M':w[i,2]:=2;
        'L':w[i,2]:=3;
        'X':w[i,2]:=4;
        'T':w[i,2]:=5;
      end;
      if i<n
        then read(s)
        else readln;
    end;
    m:=0;
    for i:=1 to 5 do
    begin
      read(x);
      num[i,1]:=m+1;
      num[i,2]:=m+x;
      m:=m+x;
    end;
    readln;
    readln;
    read(s);
    fillchar(a,sizeof(a),false);
    for i:=1 to n do
      for j:=num[w[i,1],1] to num[w[i,2],2] do
        a[i,j]:=true;
    fillchar(link,sizeof(link),0);
    ans:=0;
    for i:=1 to n do
    begin
      fillchar(v,sizeof(v),true);
      if find(i) then inc(ans);
    end;
    if ans=n
      then writeln('T-shirts rock!')
      else writeln('I',chr(39),'d rather not wear a shirt anyway...');
  end;
end.


你可能感兴趣的:(poj 2584 T-Shirt Gumbo 最大匹配)