UVA-11167 Monkeys in the Emei Mountain(区间模型最大流+输出方案)
题目大意:有n只猴子,每只猴子都有一组参数(v,a,b),表示这只猴子在时间段[a,b]之间必须要喝v个单位水,并且每个时间单位只能和一个单位水,每次至少喝一个单位。但是只有一个水池,并且这个水池最多只允许m只猴子同时喝水。问能否满足所有的猴子喝水,若能,输出任意一种可行的方案。
题目分析:将每个猴子和每个喝水区间视作节点。将每只猴子向它对应的区间连弧,容量为该区间上能喝水的总单位数;从源点向每只猴子建弧,容量为对应猴子的总需求量;从每个区间向汇点建弧,容量为该区间单位长度乘以m,表示在该区间最多允许有m只猴子同时喝水。求得最大流看是否能满足最大需求,如果能,则输出方案,其中,猴子节点连向区间节点的弧上的容量便是一种可行方案,最后要注意区间合并。
代码如下:
# include<iostream>
# include<cstdio>
# include<cmath>
# include<string>
# include<vector>
# include<list>
# include<set>
# include<map>
# include<queue>
# include<cstring>
# include<algorithm>
using namespace std; # define LL long long
# define REP(i,s,n) for(int i=s;i<n;++i)
# define CL(a,b) memset(a,b,sizeof(a))
# define CLL(a,b,n) fill(a,a+n,b) const double inf=1e30;
const int INF=1<<30;
const int N=50005; ///////////////////////////////////
struct Edge
{
int fr,to,cap,fw;
Edge(int _fr,int _to,int _cap,int _fw):fr(_fr),to(_to),cap(_cap),fw(_fw){}
};
struct Dinic{
vector<Edge>edges;
vector<int>G[N];
int d[N],vis[N],cur[N];
int s,t; void init(int n,int s,int t){
this->s=s,this->t=t;
REP(i,0,n) G[i].clear();
edges.clear();
} void addEdge(int u,int v,int cap)
{
edges.push_back(Edge(u,v,cap,0));
edges.push_back(Edge(v,u,0,0));
int len=edges.size();
G[u].push_back(len-2);
G[v].push_back(len-1);
} bool BFS()
{
CL(vis,0);
d[s]=0;
vis[s]=1;
queue<int>q;
q.push(s);
while(!q.empty()){
int x=q.front();
q.pop();
REP(i,0,G[x].size()){
Edge &e=edges[G[x][i]];
if(!vis[e.to]&&e.cap>e.fw){
d[e.to]=d[x]+1;
vis[e.to]=1;
q.push(e.to);
}
}
}
return vis[t];
} int DFS(int x,int a)
{
if(x==t||a==0) return a;
int flow=0,f;
for(int &i=cur[x];i<G[x].size();++i){
Edge &e=edges[G[x][i]];
if(d[e.to]==d[x]+1&&(f=DFS(e.to,min(a,e.cap-e.fw)))>0){
e.fw+=f;
edges[G[x][i]^1].fw-=f;
flow+=f;
a-=f;
if(a==0) break;
}
}
return flow;
} int MaxFlow()
{
int flow=0;
while(BFS()){
CL(cur,0);
flow+=DFS(s,INF);
}
return flow;
}
};
Dinic dinic;
/////////////////////////////////// struct Monkey
{
int v,l,r;
};
Monkey mon[105];
int n,m,sum,T[N];
vector<int>Time; int getID(int x)
{
return lower_bound(Time.begin(),Time.end(),x)-Time.begin();
} int main()
{
int cas=0;
while(scanf("%d",&n)&&n)
{
scanf("%d",&m);
sum=0;
Time.clear();
REP(i,1,n+1){
scanf("%d%d%d",&mon[i].v,&mon[i].l,&mon[i].r);
sum+=mon[i].v;
Time.push_back(mon[i].l);
Time.push_back(mon[i].r);
}
sort(Time.begin(),Time.end());
vector<int>::iterator it=unique(Time.begin(),Time.end());
Time.erase(it,Time.end());
int len=Time.size();
dinic.init(n+len+2,0,n+len+1);
REP(i,1,n+1){
dinic.addEdge(0,i,mon[i].v);
int a=getID(mon[i].l);
int b=getID(mon[i].r);
REP(j,a,b) dinic.addEdge(i,j+n+1,Time[j+1]-Time[j]);
}
REP(j,0,len-1) dinic.addEdge(j+n+1,n+len+1,m*(Time[j+1]-Time[j]));
int flow=dinic.MaxFlow(); /*for(int i=0;i<dinic.edges.size();i+=2){
Edge &e=dinic.edges[i];
cout<<e.fr<<' '<<e.to<<' '<<e.cap<<' '<<e.fw<<endl;
}*/ if(flow!=sum){
printf("Case %d: No\n",++cas);
}else{
printf("Case %d: Yes\n",++cas);
REP(i,0,len) T[i]=Time[i];
REP(i,1,n+1){
vector<int>temp;
REP(j,0,dinic.G[i].size()){
Edge &e=dinic.edges[dinic.G[i][j]];
if(e.fw<=0) continue;
int x=e.to-n-1;
temp.push_back(T[x]);
temp.push_back(min(Time[x+1],T[x]+e.fw));
T[x]+=e.fw;
if(T[x]>=Time[x+1]){
T[x]=Time[x]+T[x]-Time[x+1];
if(T[x]>Time[x]){
temp.push_back(Time[x]);
temp.push_back(T[x]);
}
}
}
sort(temp.begin(),temp.end());
for(int j=0;j+1<temp.size();){
if(temp[j]==temp[j+1]){
temp.erase(temp.begin()+j);
temp.erase(temp.begin()+j);
}else
++j;
}
printf("%d",temp.size()/2);
for(int j=0;j<temp.size();j+=2)
printf(" (%d,%d)",temp[j],temp[j+1]);
printf("\n");
}
}
}
return 0;
}
UVA-11167 Monkeys in the Emei Mountain(区间模型最大流+输出方案)的更多相关文章
- UVa 11167 Monkeys in the Emei Mountain (最大流)
题意:雪雪是一只猴子.它在每天的 2:00 —— 9:00之间非常渴,所以在这个期间它必须喝掉2个单位的水.它可以多次喝水,只要它喝水的总量是2.它从不多喝,在一小时内他只能喝一个单位的水.所以它喝水 ...
- UVa11167 Monkeys in the Emei Mountain(最大流)
题目大概说有n只猴子,猴子们在某个时间段需要喝vi时间的水,各个单位时间段最多允许m只猴子同时喝水,问猴子们能否成功喝水并输出一个可行的方案,输出方案的时间段区间要从小到大排序并且合并连续的区间. 首 ...
- 紫书 例题 11-13 UVa 10735(混合图的欧拉回路)(最大流)
这道题写了两个多小时-- 首先讲一下怎么建模 我们的目的是让所有点的出度等于入度 那么我们可以把点分为两部分, 一部分出度大于入度, 一部分入度大于出度 那么显然, 按照书里的思路,将边方向后,就相当 ...
- UVa 1640 The Counting Problem (数学,区间计数)
题意:给定两个数m, n,求从 m 到 n 中0-9数字各出现了多少次. 析:看起来挺简单的,其实并不好做,因为有容易想乱了.主要思路应该是这样的,分区间计数,先从个位进行计,一步一步的计算过来.都从 ...
- UVA 11584 Partitioning by Palindromes (字符串区间dp)
题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem ...
- UVA Live Archive 4394 String painter(区间dp)
区间dp,两个str一起考虑很难转移. 看了别人题解以后才知道是做两次dp. dp1.str1最坏情况下和str2完全不相同,相当于从空白串开始刷. 对于一个区间,有两种刷法,一起刷,或者分开来刷. ...
- UVA 10003 cuting sticks 切木棍 (区间dp)
区间dp,切割dp[i][j]的花费和切法无关(无后效性) dp[i][j]表示区间i,j的花费,于是只要枚举切割方法就行了,区间就划分成更小的区间了.O(n^3) 四边形不等式尚待学习 #inclu ...
- UVA 1626 Brackets sequence(括号匹配 + 区间DP)
http://acm.hust.edu.cn/vjudge/contest/view.action?cid=105116#problem/E 题意:添加最少的括号,让每个括号都能匹配并输出 分析:dp ...
- 【UVA】10891 Game of Sum(区间dp)
题目 传送门:QWQ 分析 大力dp.用$ dp[i][j] $表示$ [i,j] $A能得到的最高分 我看到博弈论就怂... 代码 #include <bits/stdc++.h> us ...
随机推荐
- ubuntu16.04下安装pcl点云库
安装依赖项 sudo apt-get update sudo apt-get install git build-essential linux-libc-dev sudo apt-get insta ...
- Python开发【Tornado】:异步Web服务(一)
异步Web服务 前言: 到目前为止,我们已经看到了许多使Tornado成为一个Web应用强有力框架的功能.它的简单性.易用性和便捷性使其有足够的理由成为许多Web项目的不错的选择.然而,Tornado ...
- Day04 dom详解及js事件
day04 dom详解 DOM的基础 Document对象 Element对象 Node对象 innerHTML 事件处理 表单验证 上次课内容回顾: JS中ECMAScript用法: JS定义变 ...
- AOP切点表达式
Aspectj切入点语法定义 在使用spring框架配置AOP的时候,不管是通过XML配置文件还是注解的方式都需要定义pointcut"切入点" 例如定义切入点表达式 execu ...
- Redux 入门教程
Redux 入门教程(三):React-Redux 的用法(53@2016.09.21) Redux 入门教程(二):中间件与异步操作(32@2016.09.20) Redux 入门教程(一):基本用 ...
- [Err]1418 This function has none of DETERMINISTIC,NO SQL,or R
----------------------------------------------------------------------------------------------- ...
- HDU1796How many integers can you find(容斥原理)
在计数时,必须注意无一重复,无一遗漏.为了使重叠部分不被重复计算,人们研究出一种新的计数方法,这种方法的基本思想是:先不考虑重叠的情况,把包含于某内容中的所有对象的数目先计算出来,然后再把计数时重复计 ...
- CSS控制列表样式属性list-style有哪些?怎么用?
CSS列表样式属性list-style有哪些类型?不同类型CSS控制列表样式使用时该注意什么? 这是W3Cschool用户Shirley于2016-11-10在W3Cschool编程问答提出的问题.云 ...
- Spring整合Mybatis 之分页插件使用
[分页插件项目中的正式代码一共有个5个Java文件,这5个文件的说明如下] Page<E>[必须]:分页参数类,该类继承ArrayList,虽然分页查询返回的结果实际类型是Page< ...
- vue-router的hash模式与history模式的对比
Vue-router 中hash模式和history模式的关系在vue的路由配置中有mode选项 最直观的区别就是在url中 hash 带了一个很丑的 # 而history是没有#的mode:&quo ...