hdu 3189(网络流+二分枚举)
| Time Limit: 1000MS | Memory Limit: 65536K | |
| Total Submissions: 6422 | Accepted: 2202 |
Description
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
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
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
Hint
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.
#include <stdio.h>
#include <algorithm>
#include <queue>
#include <string.h>
#include <math.h>
#include <iostream>
#include <math.h>
using namespace std;
const int N = ;
const int INF = ;
struct Edge{
int v,next;
int w;
}edge[N*N];
struct Cow{
int love[];
}cow[N];
int head[N];
int level[N];
int graph[N][N],dis[N][N],cap[N];
int tot;
void init(){
memset(head,-,sizeof(head));
tot=;
}
void addEdge(int u,int v,int w,int &k){
edge[k].v = v,edge[k].w=w,edge[k].next=head[u],head[u]=k++;
edge[k].v = u,edge[k].w=,edge[k].next=head[v],head[v]=k++;
}
int BFS(int src,int des){
queue<int >q;
memset(level,,sizeof(level));
level[src]=;
q.push(src);
while(!q.empty()){
int u = q.front();
q.pop();
if(u==des) return ;
for(int k = head[u];k!=-;k=edge[k].next){
int v = edge[k].v;
int w = edge[k].w;
if(level[v]==&&w!=){
level[v]=level[u]+;
q.push(v);
}
}
}
return -;
}
int dfs(int u,int des,int increaseRoad){
if(u==des) return increaseRoad;
int ret=;
for(int k=head[u];k!=-;k=edge[k].next){
int v = edge[k].v;
int w = edge[k].w;
if(level[v]==level[u]+&&w!=){
int MIN = min(increaseRoad-ret,w);
w = dfs(v,des,MIN);
if(w>){
edge[k].w -=w;
edge[k^].w+=w;
ret+=w;
if(ret==increaseRoad) return ret;
}else level[v] = -;
}
}
return ret;
}
int Dinic(int src,int des){
int ans = ;
while(BFS(src,des)!=-) ans+=dfs(src,des,INF);
return ans;
}
int n,b,src,des;
int build(int t,int mid){
init();
for(int i=;i<=b;i++){
addEdge(src,i,cap[i],tot);
}
for(int i=;i<=n;i++){
addEdge(i+b,des,,tot);
}
for(int i=t;i<=t+mid-&&i<=b;i++){
for(int j=;j<=n;j++){
addEdge(cow[j].love[i],j+b,,tot);
}
}
return Dinic(src,des);
}
int main(){
scanf("%d%d",&n,&b);
src = ,des = n+b+;
for(int i=;i<=n;i++){
for(int j=;j<=b;j++){
scanf("%d",&cow[i].love[j]);
}
}
for(int i=;i<=b;i++) scanf("%d",&cap[i]);
int l =,r = b;
int ans = b;
while(l<=r){
int mid = (l+r)>>; ///差值
bool flag = false;
for(int i=;i<=b;i++){ ///枚举最小值
if(build(i,mid)==n) {
flag = ;
break;
}
}
if(flag) {
ans = mid;
r = mid-;
}else l = mid+;
}
printf("%d\n",ans);
}
hdu 3189(网络流+二分枚举)的更多相关文章
- 无题II hdu 2236(二分枚举区间)
分析:只需要用二分找一个区间,然后不断枚举这个区间是否可以达到最大匹配,一直二分到答案为止. 代码: =============================================== ...
- hdu 5289 rmp+二分+枚举后界 or单调队列 ****
好题~~ 给你n个数和k,求有多少的区间使得区间内部任意两个数的差值小于k,输出符合要求的区间个数,枚举后界~~ 又是一种没见过的方法,太弱了/(ㄒoㄒ)/~~ #include <cstdio ...
- HDU 1669 Jamie's Contact Groups(多重匹配+二分枚举)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1669 题目大意: 给你各个人可以属于的组,把这些人分组,使这些组中人数最多的组人数最少,并输出这个人数 ...
- POJ 3189——Steady Cow Assignment——————【多重匹配、二分枚举区间长度】
Steady Cow Assignment Time Limit:1000MS Memory Limit:65536KB 64bit IO Format:%I64d & %I ...
- hdu 5248 序列变换(二分枚举)
Problem Description 给定序列A={A1,A2,...,An}, 要求改变序列A中的某些元素,形成一个严格单调的序列B(严格单调的定义为:Bi<Bi+,≤i<N). 我们 ...
- hdu 4430 二分+枚举
/* 二分+枚举 枚举k会超时,枚举r还要优化,有可能会超64 */ #include<stdio.h> #include<math.h> #define ll __int64 ...
- BFS+状态压缩DP+二分枚举+TSP
http://acm.hdu.edu.cn/showproblem.php?pid=3681 Prison Break Time Limit: 5000/2000 MS (Java/Others) ...
- FZU-2216 The Longest Straight (二分枚举)
题目大意:给n个0~m之间的数,如果是0,那么0可以变为任意的一个1~m之间的一个数.从中选出若干个数,使构成一个连续的序列.问能构成的最长序列的长度为多少? 题目分析:枚举连续序列的起点,二分枚举二 ...
- hdu 4768 Flyer 二分
思路:由于最多只有一个是奇数,所以二分枚举这个点,每次判断这个点的左边区间段所有点的和作为 二分的依据. 代码如下: #include<iostream> #include<cstd ...
随机推荐
- centos7无法切换startx
centos光盘安装后,显示命令行模式,通过startx无法进入图形界面? 解决方法:1.使用yum grouplist查看,根据显示的结果采用不同的界面格式,我用的是 yum groupinstal ...
- day24 01 初识继承
day24 01 初识继承 面向对象的三大特性:继承,多态,封装 一.继承的概念 继承:是一种创建新类的方式,新建的类可以继承一个或者多个父类,父类又可称基类或超类,新建的类称为派生类或者子类 cla ...
- 字符串:HDU3064-最长回文
最长回文 Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Problem Descri ...
- kettle-学习参考
一 关于Kettle Kettle是一款国外开源的ETL工具,纯java编写,数据抽取高效稳定的数据迁移工具.Kettle中有两种脚本文件,transformation和job,transf ...
- 创建dll及使用
一.创建动态链接库文件 ** 1.打开VS2013,选择文件,新建工程 2.选择新建W32控制台应用程序,这里将工程名改为makeDLL 3.在应用程序类型中选择DLL,点击完成 4.完成以上步 ...
- Could not load file or assembly 'AjaxControlToolkit' or one of its dependencies
Could not load file or assembly 'AjaxControlToolkit' or one of its dependencies. API 调用退出异常. (Except ...
- 如何安装mongodb.msi
到MongoDB官网下载MongoDB软件:mongodb-win32-x86_64-2008plus-ssl-3.0.2-signed.msi, 放在想要安装的地方: 如:d:\MongoDB\ 2 ...
- Python学习笔记——jupyter notebook 入门和中文pdf输出方案
简单粗暴的安装 对于懒人而言,我还是喜欢直接安装python的集成开发环境 anaconda 多个内核控制 jupyter官网 1). 同时支持python2 和python 3 conda crea ...
- [小技巧]使用set对列表去重,并保持列表原来顺序
- PHP魔术函数、魔术常量、预定义常量
一.魔术函数(13个) 1.__construct() 实例化对象时被调用, 当__construct和以类名为函数名的函数同时存在时,__construct将被调用,另一个不被调用. 2.__des ...