您的位置:首页 > 其它

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

2016-07-02 22:57 381 查看
有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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  多重匹配