poj3189 Steady Cow Assignment(枚举+多重匹配)

来源:互联网 发布:java的环境变量配置 编辑:程序博客网 时间:2024/05/29 06:30

有n头牛和b个棚,每个棚有容量上限。每头牛对每个棚有个喜欢程度,现在给牛分配住棚且棚中牛的数目不能超过该棚的上限。

先输入n,b。然后n行,每行有b个数字x[j],表示该头牛对棚子x[j]的喜欢程度是j。

现在求一种分配方法使得任意两头牛对所在棚的满意程度的差值最小,输出最小差值。

方法:枚举棚子满意度的上下限[low, high],然后做多重二分图匹配。

const int maxn = 1010;const int maxm = 21;int n, b;int like[maxn][maxm];int linker[maxm][maxn];int top[maxm];int num[maxm];bool mark[maxm];int low, high;bool dfs(int u) {    for (int v = 1;v <= b;++v) {        if (!mark[v] && low <= like[u][v] && like[u][v] <= high) {            mark[v] = true;            if (top[v] < num[v]) {                linker[v][top[v]++] = u;                return true;            }            for (int i = 0;i < top[v];++i) {                if (dfs(linker[v][i])) {                    linker[v][i] = u;                    return true;                }            }        }    }    return false;}bool hungary() {    memset(top, 0,sizeof top);    for (int i = 1;i <= n;++i) {        memset(mark, false,sizeof mark);        if (!dfs(i)) return false;    }    return true;}void solve() {    low = high = 1;    int ans = b;    while(low <= high && high <= b) {        if (hungary()) {            ans = min(ans, high - low + 1);            low++;            // bug;        }else high++;    }    cout << ans << endl;}int main(int argc, const char * argv[]){        // freopen("in.txt","r",stdin);    // freopen("out.txt","w",stdout);    // clock_t _ = clock();    while(~scanf("%d%d", &n, &b)) {        int u, v;        for (int i = 1;i <= n;++i) {            for (int j = 1;j <= b;++j) {                scanf("%d", &v);                like[i][v] = j;            }        }        for (int i = 1;i <= b;++i)            scanf("%d", &num[i]);        solve();    }    // printf("\nTime cost: %.2fs\n", 1.0 * (clock() - _) / CLOCKS_PER_SEC);    return 0;}
0 0