| Time Limit: 1000MS | Memory Limit: 65536K | |
| Total Submissions: 6023 | Accepted: 2078 |
Description
Input
Output
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头牛,m个牛棚,每个牛棚都有一定的容量(就是最多能装多少只牛),然后每只牛对每个牛圈的喜好度不同(就是所有牛圈在每个牛心中都有一个排名),然后要求所有的牛都进猪圈,牛棚在牛心中的排名差计算方法为:所有牛中最大排名和最小排名之差。问最小的排名差。
英语不好太坑了 ,理解错了题意,以测试数据举例:
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
前6行是每头牛对牛棚的排名, 第二行2 3 1 4 代表的是 对第二头牛而言,第二个牛棚排第一,第三个牛棚排第二,第一个牛棚排第三,第四个牛棚排第四。
不是第一个牛棚排第二,第二个牛棚排第三,第三个牛棚排第一,第四个牛棚排第四。这点理解搓个 ,wa了好多遍,英语不好真是要哭了。
解析:这一题其实不难,数据比较小,可以用最大流来写,建图有点麻烦,下面是建图过程:
(1)首先虚拟一个源点,汇点。
(2)源点向每头牛建边, 权值为1,
(3)牛棚向汇点建边,权值为每个牛棚的容量。
(4)枚举牛棚的最差排名和最好排名(即枚举排名差) ,在这个排名之内牛和这个牛棚建边。
看看每种情况判断是否合法(是否满流),取最小值。
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#define maxn 1200
#define maxm 100005
#define INF 0x3f3f3f3f
using namespace std;
int n, m;
struct node {
int u, v, cap, flow, next;
};
node edge[maxm];
int head[maxn], cnt;
int cur[maxn];
int dist[maxn], vis[maxn];
int num[maxn];//每个牛棚的容量
int val[1200][25];
void init(){
cnt = 0;
memset(head, -1, sizeof(head));
}
void add(int u, int v, int w){
node E;
edge[cnt] = {u, v, w, 0, head[u]};
head[u] = cnt++;
edge[cnt] = {v, u, 0, 0 ,head[v]};
head[v] = cnt++;
}
void input(){
for(int i = 1; i <= n; ++i)
for(int j = 1; j <= m; ++j)
scanf("%d", &val[i][j]);
for(int i = 1; i <= m; ++i){
scanf("%d", &num[i]);
}
}
void getmap(int l, int r){
for(int i = 1; i <= n; ++i)
add(0, i, 1);
for(int j = 1; j <= m; ++j)
add(n + j, n + m + 1, num[j]);
// for(int i = 1; i <= n; ++i)
// for(int j = 1; j <= m; ++j)
// if(val[i][j] >= l && val[i][j] <= r)
// add(i, j + n, 1);
for(int i = 1; i <= n; ++i)
for(int j = l; j <= r; ++j)
add(i, val[i][j] + n, 1);
}
bool BFS(int st ,int ed){
queue<int>q;
memset(vis, 0 ,sizeof(vis));
memset(dist, -1, sizeof(dist));
vis[st] = 1;
dist[st] = 0;
q.push(st);
while(!q.empty()){
int u = q.front();
q.pop();
for(int i = head[u]; i != -1; i = edge[i].next){
node E = edge[i];
if(!vis[E.v] && E.cap > E.flow){
vis[E.v] = 1;
dist[E.v] = dist[u] + 1;
if(E.v == ed)
return true;
q.push(E.v);
}
}
}
return false;
}
int DFS(int x, int ed, int a){
if(x == ed || a == 0)
return a;
int flow = 0, f;
for(int &i = cur[x]; i != -1; i = edge[i].next){
node &E = edge[i];
if(dist[E.v] == dist[x] + 1 && (f = DFS(E.v, ed, min(a, E.cap - E.flow))) > 0){
E.flow += f;
edge[i ^ 1].flow -= f;
a -= f;
flow += f;
if(a == 0)
break;
}
}
return flow;
}
int maxflow(int st, int ed){
int flowsum = 0;
while(BFS(st,ed)){
memcpy(cur, head, sizeof(head));
flowsum += DFS(st, ed, INF);
}
return flowsum;
}
int main(){
while(scanf("%d%d", &n, &m) != EOF){
input();
int ans = INF;
for(int i = 1; i <= m; ++i){//枚举排名的下界
for(int j = i; j <= m; ++j){//枚举排名的上界
init();
getmap(i, j);
if(maxflow(0, n + m + 1) == n)
ans = min(ans, j - i + 1);
}
}
printf("%d\n", ans);
}
return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
POJ 3189--Steady Cow Assignment【二分图多重匹配 && 最大流求解 && 枚举 && 经典】
原文地址:http://blog.csdn.net/hpuhjh/article/details/48025947