POJ3189 Steady Cow Assignment

题目链接:https://vjudge.net/problem/POJ-3189

题目大意:

  有(N)头牛,(B)个牛棚,每头牛对于不同牛棚的满意程度有大小之分,但每个牛棚的容量都是有限的。问如何安排可以使得所有牛对于自己的牛棚的最大满意程度和最小满意程度的差距最小,求出这个区间的长度。

知识点:  匹配、匈牙利算法

解题思路:

  先二分长度,然后枚举起点,在确定好区间起点终点的前提下跑匈牙利算法(权值在区间外的边相当于不存在)。因为是多重匹配(即一个牛棚有可能匹配多头牛),所以需要改一下模板。

AC代码:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 
 5 using namespace std;
 6 int G[1010][25];
 7 int cap[25];
 8 int N,B;
 9 bool used[25];
10 int to[25][1000];
11 
12 bool finds(int x,int s,int e){
13     for(int j=1;j<=B;j++){
14         if(G[x][j]>=s&&G[x][j]<=e&&!used[j]){
15             used[j]=true;
16             for(int k=0;k<cap[j];k++){  //遍历j牛棚的所有位置
17                 if(to[j][k]==0||finds(to[j][k],s,e)){   //对于j牛棚的第k个位置的查询
18                     to[j][k]=x;
19                     return true;
20                 }
21             }
22         }
23     }
24     return false;
25 }
26 bool can(int m){
27     for(int s=1;s+m-1<=B;s++){
28         memset(to,0,sizeof(to));
29         int has=0;
30         for(int i=1;i<=N;i++){
31             memset(used,false,sizeof(used));
32             if(finds(i,s,s+m-1))    has++;
33             else    break;
34         }
35         if(has==N)  return true;
36     }
37     return false;
38 }
39 int main(){
40     int val;
41     scanf("%d%d",&N,&B);
42     for(int i=1;i<=N;i++){
43         for(int j=1;j<=B;j++){
44             scanf("%d",&val);
45             G[i][val]=j;
46         }
47     }
48     for(int j=1;j<=B;j++)   scanf("%d",&cap[j]);
49     int l=1,r=B;
50     int ans=1;
51     while(l<=r){
52         int m=(l+r)>>1;
53         if(can(m)){
54             ans=m;
55             r=m-1;
56         }
57         else
58             l=m+1;
59     }
60     printf("%d
",ans);
61 
62     return 0;
63 }
“这些年我一直提醒自己一件事情,千万不要自己感动自己。大部分人看似的努力,不过是愚蠢导致的。什么熬夜看书到天亮,连续几天只睡几小时,多久没放假了,如果这些东西也值得夸耀,那么富士康流水线上任何一个人都比你努力多了。人难免天生有自怜的情绪,唯有时刻保持清醒,才能看清真正的价值在哪里。”
原文地址:https://www.cnblogs.com/Blogggggg/p/8429863.html