酒店之王

題目描述 Description
XX酒店的老闆想成爲酒店之王,本着這種希望,第一步要將酒店變得人性化。由於很多來住店的旅客有自己喜好的房間色調、陽光等,也有自己所愛的菜,但是該酒店只有p間房間,一天只有固定的q道不同的菜。
有一天來了n個客人,每個客人說出了自己喜歡哪些房間,喜歡哪道菜。但是很不幸,可能做不到讓所有顧客滿意(滿意的條件是住進喜歡的房間,吃到喜歡的菜)。
這裏要怎麼分配,能使最多顧客滿意呢?

輸入輸出格式 Input/output
輸入格式:
第一行給出三個正整數表示n,p,q(<=100)。
之後n行,每行p個數包含0或1,第i個數表示喜不喜歡第i個房間(1表示喜歡,0表示不喜歡)。
之後n行,每行q個數,表示喜不喜歡第i道菜。
輸出格式:
最大的顧客滿意數。

輸入樣例:
2 2 2
1 0
1 0
1 1
1 1

輸出樣例:
1

題解:裸的網絡流。別忘了把一個人拆成兩個人。

#include
#include
using namespace std;

const int INF=~0U>>2;//極大值
int s=0,t;
int n,p,q;
int map[405][405];
int dis[405],sumd[405],now[405];
int fanhui[405],pre[405];
int ans=0;

void init()
{
 scanf("%d%d%d",&n,&p,&q);
 t=2*n+p+q+1;

 for (int i=1; i<=p; i++) map[0][i]=1;  
 for (int i=1; i<=n; i++) map[i+p][i+p+n]=1;  
 for (int i=1; i<=q; i++) map[i+p+n+n][t]=1;  
 for (int i=1; i<=n; i++)  
   for (int j=1; j<=p; j++) cin >> map[j][i+p];  
 for (int i=1; i<=n; i++)  
   for(int j=1; j<=q; j++) cin >> map[i+p+n][j+p+n+n];  //四排點
}

void sap()
{
 sumd[0]=t+1;
 int i=s;
 now[i]=0;
 int flow=INF;
 while (dis[s]
 {
  fanhui[i]=flow;
  bool flag=false;
  for (int j=0; j<=t; j++)
    if (map[i][j]>0 && dis[i]==dis[j]+1)
    {     
     flag=true;
     if (map[i][j]
     now[i]=j;
     pre[j]=i;
     i=j;
     if (i==t)
     {
      ans++;
      while (pre[i]!=0)
      {
       int k=pre[i];
       map[k][i]-=flow;
       map[i][k]+=flow;
       i=k;
      }
      map[s][i]-=flow;
      map[i][s]+=flow;
      i=s;
     }
     break;
    }
  if (flag) continue;
  int kk=INF;//kk是最小的標號
  for (int j=0; j<=t; j++)
    if (dis[j]0) kk=dis[j];
  sumd[dis[i]]--;
  if (sumd[dis[i]]==0) break;
  dis[i]=kk+1;
  sumd[dis[i]]++;
  flow=fanhui[i];
  if (i!=0) i=pre[i];
 }
 cout << ans;
 return;
}

int main()
{
 init();
 sap();
 return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章