解题报告 之 POJ3189 Steady Cow Assignment

来源:互联网 发布:apache tools 编辑:程序博客网 时间:2024/06/09 01:43

解题报告 之 POJ3189 Steady Cow Assignment


Description

Farmer John's N (1 <= N <= 1000) cows each reside in one of B (1 <= B <= 20) barns which, of course, have limited capacity. Some cows really like their current barn, and some are not so happy. 

FJ would like to rearrange the cows such that the cows are as equally happy as possible, even if that means all the cows hate their assigned barn. 

Each cow gives FJ the order in which she prefers the barns. A cow's happiness with a particular assignment is her ranking of her barn. Your job is to find an assignment of cows to barns such that no barn's capacity is exceeded and the size of the range (i.e., one more than the positive difference between the the highest-ranked barn chosen and that lowest-ranked barn chosen) of barn rankings the cows give their assigned barns is as small as possible.

Input

Line 1: Two space-separated integers, N and B 

Lines 2..N+1: Each line contains B space-separated integers which are exactly 1..B sorted into some order. The first integer on line i+1 is the number of the cow i's top-choice barn, the second integer on that line is the number of the i'th cow's second-choice barn, and so on. 

Line N+2: B space-separated integers, respectively the capacity of the first barn, then the capacity of the second, and so on. The sum of these numbers is guaranteed to be at least N.

Output

Line 1: One integer, the size of the minumum range of barn rankings the cows give their assigned barns, including the endpoints.

Sample Input

6 41 2 3 42 3 1 44 2 3 13 1 2 41 3 4 21 4 2 32 1 3 2

Sample Output

2

Hint

Explanation of the sample: 

Each cow can be assigned to her first or second choice: barn 1 gets cows 1 and 5, barn 2 gets cow 2, barn 3 gets cow 4, and barn 4 gets cows 3 and 6.


题目大意:有n头牛,有b个棚,对于每头牛依次输入每个棚在它看来的排名(1~b)。最后一行输入每个棚的容量。问在保证所有牛都有棚住的前提下,所有牛中,所住的棚的最高级和最低等的差值最小是多少?


分析:首先大体上很明显是最大流。重点在于如何求得这个差值的最小值。用m表示差值最小值,初值为INF。这里采用的办法是枚举,但是不能用双重循环不然会超时,除非双重循环的前提下加上if(high-low+1>m) break;  。而我采用的方法是设置low=high=1,然后如果当前条件满足的话,则low++缩短距离,如果不满足则high++。最终得答案即可。


最大流的建图方法是:超级源点与所有牛连,边负载为1。将所有low<= flow <=high 的牛与棚连接,负载为1。然后将所有棚与超级汇点连接,负载为棚容量。然后Dinic跑一遍即可。


上代码:

#include<iostream>#include<algorithm>#include<queue>#include<cstdio>using namespace std;const int MAXN = 1300;const int MAXM = 50000;const int INF = 0x3f3f3f3f;struct Edge{int to, next, cap;};Edge edge[MAXM];int r[MAXN][MAXN];int cap[MAXN];int level[MAXN];int head[MAXN];int cnt, src, des;void addedge(int from, int to, int cap){edge[cnt].to = to;edge[cnt].cap = cap;edge[cnt].next = head[from];head[from] = cnt++;edge[cnt].to = from;edge[cnt].cap = 0;edge[cnt].next = head[to];head[to] = cnt++;}int bfs(){queue<int> q;while (!q.empty())q.pop();memset(level, -1, sizeof level);level[src] = 0;q.push(src);while (!q.empty()){int u = q.front();q.pop();for (int i = head[u]; i != -1; i = edge[i].next){int v = edge[i].to;if (edge[i].cap > 0 && level[v] == -1){level[v] = level[u] + 1;q.push(v);}}}return level[des] != -1;}int dfs(int u, int f){if (u == des) return f;int tem;for (int i = head[u]; i != -1; i = edge[i].next){int v = edge[i].to;if (edge[i].cap > 0 && level[v] == level[u] + 1){tem = dfs(v, min(f, edge[i].cap));if (tem > 0){edge[i].cap -= tem;edge[i ^ 1].cap += tem;return tem;}}}level[u] = -1;return 0;}int Dinic(){int ans = 0, tem;while (bfs()){while (tem = dfs(src, INF)){ans += tem;}}return ans;}int main(){int n, b;while (scanf("%d%d", &n, &b)){src = 0;des = n + b + 1;for (int i = 1; i <= n; i++){for (int j = 1; j <= b; j++){scanf("%d", &r[i][j]);}}for (int i = n + 1; i <= n + b; i++){scanf("%d", &cap[i]);}int m = INF;int low = 1, high = 1;while (low <= high&&high <= b){    memset(head, -1, sizeof head);cnt = 0;for (int i = 1; i <= n; i++){addedge(src, i, 1);for (int j = low; j <= high; j++){addedge(i, r[i][j] + n, 1);}}for (int i = n + 1; i <= n + b; i++){addedge(i, des, cap[i]);}//int tem = Dinic();if (Dinic() >= n){if (high - low + 1 < m) m = high - low + 1;low++;}elsehigh++;}cout << m << endl;return 0;}}

继续签到最大流,,woho!~


0 0
原创粉丝点击