博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
UVALive - 6571 It Can Be Arranged 最大流
阅读量:5256 次
发布时间:2019-06-14

本文共 4168 字,大约阅读时间需要 13 分钟。

题目链接:

It Can Be Arranged

Time Limit: 3000MS

问题描述

Every year, several universities arrange inter-university national programming contests. ACM ICPC

Dhaka site regional competition is held every year in Dhaka and one or two teams are chosen for ACM
ICPC World Finals.
By observing these, MMR (Mission Maker Rahman) has made a plan to open a programming
school. In that school, N courses are taught. Each course is taught every day (otherwise, programmers
may forget DP while learning computational geometry!). You will be given the starting time Ai and
finishing time Bi (inclusive) of each course i (1 ≤ i ≤ N). You will be also given the number of students
registered for each course, Si (1 ≤ i ≤ N). You can safely assume no student has registered to two
different courses. MMR wants to hire some rooms of a building, named Sentinel Tower, for running that
school. Each room of Sentinel Tower has a capacity to hold as much as M students. The programmers
(students) are very restless and a little bit filthy! As a result, when coursei
is taken in a class room,
after the class is finished, it takes cleanij time to clean the room to make it tidy for starting teaching
coursej immediately just after coursei in the same room.
Your job is to help MMR to decide the minimum number of rooms need to be hired to run the
programming school.

输入

Input starts with an integer T (T ≤ 100) denoting the number of test cases. Each case starts with two

integers N (1 ≤ N ≤ 100), number of courses and M (1 ≤ M ≤ 10000), capacity of a room. Next N
lines will contain three integers Ai
, Bi (0 ≤ Ai ≤ Bi ≤ 10000000) and Si (1 ≤ Si ≤ 10000), starting
and finishing time of a course. Next N lines will contain the clean time matrix, where the i-th row will
contain N integers cleanij (1 ≤ i ≤ N, 1 ≤ j ≤ N, 0 ≤ cleanij ≤ 10000000, cleanii = 0).

输出

For each case, print the test case number, starting from 1, and the answer, minimum number of rooms

needed to be hired.

样例

sample input

3
1 5
1 60 12
0
4 1
1 100 10
50 130 3
150 200 15
80 170 7
0 2 3 4
5 0 7 8
9 10 0 12
13 14 15 0
2 1
1 10 1
12 20 1
0 2
5 0

sample output

Case 1: 3
Case 2: 22
Case 3: 2

题意

现在需要上n个课程,每个课程:(s,t,p),描述开始时间,结束时间,和上课人数。

现在有若干个最多能容纳m个人的教室,问如何用最少的教室上完所有的课。

题解

如果教室的容量没有要求,那么这将是一个经典的DAG的最少路径覆盖问题。

加了教室容量限制之后,变成了一个带权的最少路径覆盖问题。
我们可以这样建图:首先拆点,把课程i拆成i,i+n,0到i连边,i+n到2*n+1连边,边权为i课程需要的教室数,然后如果课程i上完能够接着上j,那么就连一条边权为INF的边从i到j+n。 然后跑最大流,这样跑出了的值相当于能够共用的教室数,吧总数-最大流就是答案了。

代码

#include#include
#include
#include
#include
#include
#include
#include
#define X first#define Y second#define mkp make_pair#define lson (o<<1)#define rson ((o<<1)|1)#define M (l+(r-l)/2)#define bug(a) cout<<#a<<" = "<
<
egs; vector
G[maxn]; bool vis[maxn]; int d[maxn]; int cur[maxn]; void init(int n) { this->n=n; for(int i=0; i<=n; i++) G[i].clear(); egs.clear(); } void addEdge(int from,int to,int cap) { egs.push_back(Edge(from,to,cap,0)); egs.push_back(Edge(to,from,0,0)); m=egs.size(); G[from].push_back(m-2); G[to].push_back(m-1); } bool BFS() { memset(vis,0,sizeof(vis)); queue
Q; Q.push(s); d[s]=0; vis[s]=1; while(!Q.empty()) { int x=Q.front(); Q.pop(); for(int i=0; i
e.flow) { vis[e.to]=1; d[e.to]=d[x]+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
0) { e.flow+=f; egs[G[x][i]^1].flow-=f; flow+=f; a-=f; if(a==0) break; } } return flow; } int Maxflow(int s,int t) { this->s=s; this->t=t; int flow=0; while(BFS()) { memset(cur,0,sizeof(cur)); flow+=DFS(s,INF); } return flow; }} dinic;int n,m;LL si[maxn],ti[maxn],C[maxn][maxn];int wi[maxn];void init() { dinic.init(2*n+2);}int main() { int tc,kase=0; scanf("%d",&tc); while(tc--) { scanf("%d%d",&n,&m); init(); for(int i=1; i<=n; i++) { scanf("%lld%lld%d",&si[i],&ti[i],&wi[i]); } for(int i=1; i<=n; i++) { for(int j=1; j<=n; j++) { scanf("%lld",&C[i][j]); } } int sum=0; for(int i=1; i<=n; i++) { int cap=wi[i]%m?wi[i]/m+1:wi[i]/m; sum+=cap; dinic.addEdge(0,i,cap); dinic.addEdge(i+n,2*n+1,cap); } for(int i=1; i<=n; i++) { for(int j=1; j<=n; j++) { if(ti[i]+C[i][j]

转载于:https://www.cnblogs.com/fenice/p/5744945.html

你可能感兴趣的文章
cuda api查询问题
查看>>
Windows下安装PCL点云库
查看>>
Java Swing学习:文件选择框
查看>>
【特效】隔行变色
查看>>
【学习】苹果iPhone safari浏览器样式重置修复按钮圆角bug
查看>>
【学习】js学习笔记:内置顶层函数eval()的兼容用法
查看>>
c# DES加密与解密·· 转载
查看>>
android 动态注册JNI函数过程源码分析
查看>>
Filter
查看>>
2017.02.23. 学习C#第五天,循环语句for助我脑洞大开。。。
查看>>
Spring注解
查看>>
[ASP] 使用asp读取指定文件夹的文件列表(返回xml)
查看>>
node + express 搭建服务器,修改为自动重启服务器
查看>>
用OleDb读取Excel时报错:定义了过多的列
查看>>
爱根,听闻根体欠安,吾茶饭不思夜不能寐,欲语泪先流!!!计算器!
查看>>
2017.12.22 Java序列化中你不知道的事(一)
查看>>
python--函数
查看>>
Objective-C 高级编程:iOS与OS X多线程和内存管理
查看>>
循序渐进DB2(第2版)——DBA系统管理、运维与应用案例
查看>>
jQuery插件treeview点击节点名称不展开、收缩节点 分类: Jav...
查看>>