您的位置:首页 > 其它

POJ 3189 Steady Cow Assignment(二分+多重匹配)

2014-04-08 20:34 393 查看
Sample Input
6 4
1 2 3 4
2 3 1 4
4 2 3 1
3 1 2 4
1 3 4 2
1 4 2 3
2 1 3 2      //每个牛棚的限制数目

Sample Output
2


题意:现有n头牛和b个牛棚,每个牛棚可以养的牛的数目都有一个限制c[i],表示该牛棚最多只能关c[i]头牛,每头牛对每一个牛棚都有一个喜爱值,用1到b来表示,现在要安排这些牛,使得牛棚中的牛对牛棚的最大喜爱值与最小喜爱值的差值最小. 因为喜爱值在区间[1,b],所以可以枚举该差值,设最小喜爱值为low,最大喜爱值为h igh,初始时low=high=1,如果喜爱值在[low,high]的范围内可以将这n头牛以满足题意的方式安排好,那么就增大low值以用来减小差值,而如果没有安排方案,那么就增大high值来寻找新的安排方案.

#include<stdio.h>
#include<string.h>
#include<algorithm>
#define MAXN 1010
#define MAXB 30
#define INF 0x3f3f3f3f
int N, B, yM[MAXB][MAXN], visy[MAXB], num[MAXB], limit[MAXB];
int g[MAXN][MAXB], LOW, HIGH;
void init()
{
    int i, j, k;
    for(i = 0; i < N; i ++)
        for(j = 0; j < B; j ++)
            scanf("%d", &g[i][j]), -- g[i][j];
    for(i = 0; i < B; i ++) scanf("%d", &limit[i]);
}
int searchpath(int cur)     //多重匹配 
{
    int i, y, j;
    for(i = LOW; i <= HIGH; i ++)    
        if(!visy[g[cur][i]])    //改喜爱没访问,喜爱值也就是牛棚序号 
        {
            y = g[cur][i], visy[y] = 1;
            if(num[y] < limit[y])   //当前牛棚的牛数还没超过限制数目 
            {
                yM[y][num[y] ++] = cur;    //牛棚y 的 第i只牛是 cur 
                return 1;
            }
            for(j = 0; j < num[y]; j ++)  //y牛棚的所有牛 ,找跟其他牛棚的所有匹配 。 
                if(searchpath(yM[y][j]))
                {
                    yM[y][j] = cur;
                    return 1;    
                }
        }
    return 0;
}
int match()
{
    int i;
    memset(num, 0, sizeof(num[0]) * B);
    for(i = 0; i < N; i ++)    //所有牛都有匹配,说明都能住完,有解。 
    {
        memset(visy, 0, sizeof(visy[0]) * B);
        if(!searchpath(i)) return 0;
    }
    return 1;
}
void solve()
{
    int ans = INF;
    LOW = HIGH = 0;
    while(HIGH < B)
    {
        if(!match())          //无解 
            ++ HIGH;        
        else      //以low,high的匹配有解  ,即所有牛都能住完 。low++,减少差值。继续找 
            ans = std::min(ans, HIGH - LOW + 1), ++ LOW;
    }
    printf("%d\n", ans);
}
int main()
{
    while(scanf("%d%d", &N, &B) == 2)
    {
        init();
        solve();    
    }
    return 0;    
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: