P2857 [USACO06FEB]稳定奶牛分配Steady Cow Assignment

题目描述

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.

有N头牛,B个牛棚.告诉你每头牛心里牛棚的座次,即哪个牛棚他最喜欢,哪个第2喜欢, 哪个第3喜欢,等等.但牛棚容量一定,所以每头牛分配到的牛棚在该牛心中的座次有高有低.现 在求一种最公平的方法分配牛到牛棚,使所有牛中,所居牛棚的座次最高与最低的跨度最小.

输入输出格式

输入格式:

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.

输出格式:

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

输入输出样例

输入样例#1:

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

输出样例#1:

2

说明

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.

Solution:

  画风诡异的题~(洛谷标签什么鬼啊!明显的最大流嘛~而且为什么死活$WA$一个点啊~)`~`

  我的思路其实蛮简单的,直接枚举等级差和初始等级,然后在这个范围内建图,建图方法就比较常规了:源点连容量为$1$的边到每个牛,每头牛向我们枚举的等级范围中的牛舍连容量为$1$的边,每个牛舍向汇点连容量为牛舍体积的边。

  每次跑最大流,当最大流等于牛数时,此时的等级差就是答案了。

  (话说应该没问题吧,我都想特判了,求解!~知道的请[email protected]$我~感激不尽)

代码(非$AC$):

 1 #include<bits/stdc++.h>
 2 #define il inline
 3 #define debug printf("%s %d\n",__FUNCTION__,__LINE__)
 4 #define For(i,a,b) for(int (i)=(a);(i)<=(b);(i)++)
 5 using namespace std;
 6 const int N=500005,inf=5201314;
 7 int n,m,ans,tot,s,t=1314,mp[1005][30],val[25],to[N],net[N],w[N],h[N],cnt=1,dis[5000];
 8
 9 il int gi(){
10     int a=0;char x=getchar();
11     while(x<‘0‘||x>‘9‘)x=getchar();
12     while(x>=‘0‘&&x<=‘9‘)a=(a<<3)+(a<<1)+x-48,x=getchar();
13     return a;
14 }
15
16 il void add(int x,int y,int z){
17     to[++cnt]=y,net[cnt]=h[x],h[x]=cnt,w[cnt]=z;
18     to[++cnt]=x,net[cnt]=h[y],h[y]=cnt,w[cnt]=0;
19 }
20
21 il bool bfs(){
22     queue<int>q;
23     memset(dis,-1,sizeof(dis));
24     q.push(s);dis[s]=0;
25     while(!q.empty()){
26         int u=q.front();q.pop();
27         for(int i=h[u];i;i=net[i])
28             if(dis[to[i]]==-1&&w[i]>0)dis[to[i]]=dis[u]+1,q.push(to[i]);
29     }
30     //For(i,1,n+m)cout<<dis[i]<<‘ ‘;cout<<endl;//debug;
31     return dis[t]!=-1;
32 }
33
34 il int dfs(int u,int op){
35     if(u==t)return op;
36     int flow=0,used=0;
37     for(int i=h[u];i;i=net[i]){
38         int v=to[i];
39         if(dis[v]==dis[u]+1&&w[i]>0){
40             used=dfs(v,min(op,w[i]));
41             if(!used)continue;
42             flow+=used,op-=used;
43             w[i]-=used,w[i^1]+=used;
44             if(!op)break;
45         }
46     }
47     if(!flow)dis[u]=-1;
48     return flow;
49 }
50
51 il bool work(int pos,int len){
52     tot=0;cnt=0;
53     memset(h,0,sizeof(h));
54     For(i,1,n) add(s,i,1);
55     For(i,1,m) add(i+n,t,val[i]);
56     For(i,1,n) For(j,pos,pos+len-1) add(i,mp[i][j],1);
57     while(bfs())tot+=dfs(0,inf);
58     //cout<<tot<<endl;
59     if(tot==n)return 1;
60     return 0;
61 }
62
63 int main(){
64     n=gi(),m=gi();
65     For(i,1,n) add(s,i,1);
66     For(i,1,n) For(j,1,m) mp[i][j]=gi()+n;
67     For(i,1,m) val[i]=gi();
68     For(i,1,m) For(j,1,m-i+1)if(work(j,i)){cout<<i;return 0;}
69 }

原文地址:https://www.cnblogs.com/five20/p/9103980.html

时间: 2024-11-08 21:47:03

P2857 [USACO06FEB]稳定奶牛分配Steady Cow Assignment的相关文章

POJ 3189 Steady Cow Assignment(最大流)

POJ 3189 Steady Cow Assignment 题目链接 题意:一些牛,每个牛心目中都有一个牛棚排名,然后给定每个牛棚容量,要求分配这些牛给牛棚,使得所有牛对牛棚的排名差距尽量小 思路:这种题的标准解法都是二分一个差值,枚举下界确定上界,然后建图判断,这题就利用最大流进行判断,值得一提的是dinic的效率加了减枝还是是卡着时间过的,这题理论上用sap或者二分图多重匹配会更好 代码: #include <cstdio> #include <cstring> #inclu

poj 3189 Steady Cow Assignment 【最大流】【枚举上下界 判断是否满流】

Steady Cow Assignment Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 6029   Accepted: 2083 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. So

Poj 3189 Steady Cow Assignment (多重匹配)

题目链接: Poj 3189 Steady Cow Assignment 题目描述: 有n头奶牛,m个棚,每个奶牛对每个棚都有一个喜爱程度.当然啦,棚子也是有脾气的,并不是奶牛想住进来就住进来,超出棚子的最大容量了,棚子是拒绝的.现在要给每个奶牛安家,本宝宝是一个公正无私的人类,所以要找一个奶牛喜爱程度差值最小的方案(虽然这样大家的喜爱程度可能普遍偏低,因为绝对公平并不代表合理啊),问喜爱程度的区间最小为多大? 解题思路: 每个棚子并不是住一个奶牛,所以是多重匹配咯.匹配的时候二分枚举喜爱程度的

Steady Cow Assignment(二分图多重匹配+二分)(网络流)

Steady Cow Assignment Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit Status Practice POJ 3189 Description Farmer John's N (1 <= N <= 1000) cows each reside in one of B (1 <= B <= 20) barns which, of cou

POJ 3189 Steady Cow Assignment(网络流之最大流+二分构图)

题目地址:POJ 3189 我晕啊...飞快的把白天的任务完成又有什么用...节省下来的时间活生生的被我的手残给全浪费掉了...又调了一整天,问题居然是一个地方的n和m写反了!!!反思..反思...面壁去... 这题就是二分区间,然后枚举区间位置.然后建图就行了.不多说.. 代码如下: #include <iostream> #include <stdio.h> #include <string.h> #include <stdlib.h> #include

POJ3189 Steady Cow Assignment —— 二分图多重匹配/最大流 + 二分

题目链接:https://vjudge.net/problem/POJ-3189 Steady Cow Assignment Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 6979   Accepted: 2418 Description Farmer John's N (1 <= N <= 1000) cows each reside in one of B (1 <= B <= 20) barns wh

O - Steady Cow Assignment - POJ 3189(多重匹配+枚举)

题意:有N头奶牛,M个牛棚,每个牛棚都有一个容量,并且每个牛对牛棚都有一个好感度,现在重新分配牛棚,并且使好感觉最大的和最小的差值最小. 分析:好感度貌似不多,看起来可以枚举一下的样子,先试一下把 注意:枚举确实是没问题,不过那个输入需要注意一下(错了好几次才发现),比如说第二行 2 3 1 4,意思就是这个牛最中意的牛圈是2号,其次是3号...最后一行是每个牛圈能放多少牛,输出的时候要计算端点,也就是最大的rankMax-rankmin+1 **************************

POJ 3189 Steady Cow Assignment

题意:每个奶牛对所有的牛棚有个排名(根据喜欢程度排的),每个牛棚能够入住的牛的数量有个上限,重新给牛分配牛棚,使牛棚在牛心中的排名差(所有牛中最大排名和最小排名之差)最小. 题目输入: 首先是两个数字N , B代表有N只牛B个牛棚 接下来的第一行B个数字代表每个牛棚最多能容纳多少牛. 接下来N行每行B个数字代表牛心中牛棚的排名. 我勒个去啊!真郁闷,WA了好多次终于AC发现自己错是因为重新构图后下标是从0开始的,改成下标从 1 开始的就AC了 #include<stdio.h> #includ

POJ3189 Steady Cow Assignment(二分图多重匹配)

题意: N头牛M个棚,每头牛对每个棚都有喜爱顺序 每个棚都有自己的容量 问你怎么分配使得所有牛的喜爱程度差距最小 思路: l r表示一段喜爱程度的范围 建图就按l 到 r里的棚子建 然后两个标移动从头到尾就可以扫出最小值了 /* *********************************************** Author :devil Created Time :2016/5/17 22:28:45 ****************************************