HDU 3572 最大流
2015-11-07 20:58
441 查看
最近在刷题和各种事情,忘记更新了,最近会把做的题目都更新出来
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 6018 Accepted Submission(s): 1927
Problem Description
Our geometry princess XMM has stoped her study in computational geometry to concentrate on her newly opened factory. Her factory has introduced M new machines in order to process the coming N tasks. For the i-th task, the factory has to start processing it
at or after day Si, process it for Pi days, and finish the task before or at day Ei. A machine can only work on one task at a time, and each task can be processed by at most one machine at a time. However, a task can be interrupted and processed on different
machines on different days.
Now she wonders whether he has a feasible schedule to finish all the tasks in time. She turns to you for help.
Input
On the first line comes an integer T(T<=20), indicating the number of test cases.
You are given two integer N(N<=500) and M(M<=200) on the first line of each test case. Then on each of next N lines are three integers Pi, Si and Ei (1<=Pi, Si, Ei<=500), which have the meaning described in the description. It is guaranteed that in a feasible
schedule every task that can be finished will be done before or at its end day.
Output
For each test case, print “Case x: ” first, where x is the case number. If there exists a feasible schedule to finish all the tasks, print “Yes”, otherwise print “No”.
Print a blank line after each test case.
Sample Input
2
4 3
1 3 5
1 1 4
2 3 7
3 5 9
2 2
2 1 3
1 2 2
Sample Output
Case 1: Yes
Case 2: Yes
Author
allenlowesy
Source
2010 ACM-ICPC Multi-University
Training Contest(13)——Host by UESTC
Recommend
zhouzeyong
/************************************************
Desiner:hl
time:2015/11/01
Exe.Time:187MS
Exe.Memory:5776K
题意:有M个机器,有N个任务。每个任务必须在Si 或者以后开始做,在Ei 或者之前完成,
完成任务必须处理Pi 个时间单位。其中,每个任务可以在任意(空闲)机器上工作,每个
机器的同一时刻只能工作一个任务,每个任务在同一时刻只能被一个机器工作,而且任务做
到一半可以打断,拿去其他机器做。问:能否在规定时间内把任务做完。
题解:源点到每个任务建立一条值为完成该任务需要的天数的边
任务到该任务开始到该任务结束的所有天数分别建立一条为1的边
天数到汇点建立一条为题目中机械数量的边
如果sap算出来的结果是等于他所需要的天数的。说明他们能完成
************************************************/
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <cstdio>
#include <cmath>
using namespace std;
const int MAXN = 100010 ; //点数最大值
const int MAXM = 400010 ; //边数最大值
const int INF = 0x3f3f3f3f;
int S,V,N,M;
int maxday;
struct Edge{
int to,next,cap,flow;
}edge[MAXM];//注意是MAXM
int tol;
int head[MAXN];
int gap[MAXN],dep[MAXN],pre[MAXN],cur[MAXN];
int aa[555],bb[555],cc[555];
void init(){
tol = 0;
memset(head,-1,sizeof(head));
}
void addedge(int u,int v,int w,int rw=0){
edge[tol].to = v;
edge[tol].cap = w;
edge[tol].next = head[u];
edge[tol].flow = 0;
head[u] = tol++;
edge[tol].to = u;
edge[tol].cap = rw;
edge[tol].next = head[v];
edge[tol].flow = 0;
head[v] = tol++;
}
//最大流开始
int sap(int start,int end,int N){
memset(gap,0,sizeof(gap));
memset(dep,0,sizeof(dep));
memcpy(cur,head,sizeof(head));
int u = start;
pre[u] = -1;
gap[0] = N;
int ans = 0;
while(dep[start] < N){
if(u==end){
int Min = INF;
for(int i=pre[u];i!= -1; i=pre[edge[i^1].to])
if(Min > edge[i].cap - edge[i].flow)
Min = edge[i].cap - edge[i].flow;
for(int i=pre[u];i!=-1;i=pre[edge[i^1].to]){
edge[i].flow += Min;
edge[i^1].flow -=Min;
}
u=start;
ans +=Min;
continue;
}
bool flag = false;
int v;
for(int i= cur[u];i!=-1;i=edge[i].next){
v=edge[i].to;
if(edge[i].cap-edge[i].flow&&dep[v]+1==dep[u]){
flag=true;
cur[u]=pre[v]=i;
break;
}
}
if(flag){
u=v;
continue;
}
int Min = N;
for(int i=head[u];i!= -1;i=edge[i].next)
if(edge[i].cap-edge[i].flow&&dep[edge[i].to]<Min){
Min=dep[edge[i].to];
cur[u] = i;
}
gap[dep[u]]--;
if(!gap[dep[u]]) return ans;
dep[u] = Min +1;
gap[dep[u]]++;
if(u!=start) u = edge[pre[u]^1].to;
}
return ans;
}
//最大流结束
int build(){
int i,j,k,l,m,n;
init();
for(i=1;i<=N;i++){
addedge(S,i,aa[i]);//源点到每个任务的连线为PI
for(j=bb[i];j<=cc[i];j++){
addedge(i,N+j,1); //从这个任务到这个任务开始的时间到结束的时间连一条为1的边
}
}
for(j=1;j<=maxday;j++){
addedge(j+N,V,M);
}
int orz=sap(S,V,V+1);
return orz;
}
bool solve(int su){
int i,j,k;
int ans;
ans = build();
if(ans==su){
printf("Yes\n");
}
else{
printf("No\n");
}
}
int main(){
int T;
int m,n,q,p;
int i,j,k,a,b,c;
int pisum;
scanf("%d",&T);
for(int cas=1;cas<=T;cas++){
scanf("%d%d",&N,&M);
pisum=maxday=0;
for(i=1;i<=N;i++){
scanf("%d%d%d",&aa[i],&bb[i],&cc[i]);
pisum+=aa[i];
maxday=max(maxday,cc[i]);
}
S=0;
V=N+maxday+1;
printf("Case %d: ",cas);
solve(pisum);
puts("");
}
return 0;
}
Task Schedule
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 6018 Accepted Submission(s): 1927
Problem Description
Our geometry princess XMM has stoped her study in computational geometry to concentrate on her newly opened factory. Her factory has introduced M new machines in order to process the coming N tasks. For the i-th task, the factory has to start processing it
at or after day Si, process it for Pi days, and finish the task before or at day Ei. A machine can only work on one task at a time, and each task can be processed by at most one machine at a time. However, a task can be interrupted and processed on different
machines on different days.
Now she wonders whether he has a feasible schedule to finish all the tasks in time. She turns to you for help.
Input
On the first line comes an integer T(T<=20), indicating the number of test cases.
You are given two integer N(N<=500) and M(M<=200) on the first line of each test case. Then on each of next N lines are three integers Pi, Si and Ei (1<=Pi, Si, Ei<=500), which have the meaning described in the description. It is guaranteed that in a feasible
schedule every task that can be finished will be done before or at its end day.
Output
For each test case, print “Case x: ” first, where x is the case number. If there exists a feasible schedule to finish all the tasks, print “Yes”, otherwise print “No”.
Print a blank line after each test case.
Sample Input
2
4 3
1 3 5
1 1 4
2 3 7
3 5 9
2 2
2 1 3
1 2 2
Sample Output
Case 1: Yes
Case 2: Yes
Author
allenlowesy
Source
2010 ACM-ICPC Multi-University
Training Contest(13)——Host by UESTC
Recommend
zhouzeyong
/************************************************
Desiner:hl
time:2015/11/01
Exe.Time:187MS
Exe.Memory:5776K
题意:有M个机器,有N个任务。每个任务必须在Si 或者以后开始做,在Ei 或者之前完成,
完成任务必须处理Pi 个时间单位。其中,每个任务可以在任意(空闲)机器上工作,每个
机器的同一时刻只能工作一个任务,每个任务在同一时刻只能被一个机器工作,而且任务做
到一半可以打断,拿去其他机器做。问:能否在规定时间内把任务做完。
题解:源点到每个任务建立一条值为完成该任务需要的天数的边
任务到该任务开始到该任务结束的所有天数分别建立一条为1的边
天数到汇点建立一条为题目中机械数量的边
如果sap算出来的结果是等于他所需要的天数的。说明他们能完成
************************************************/
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <cstdio>
#include <cmath>
using namespace std;
const int MAXN = 100010 ; //点数最大值
const int MAXM = 400010 ; //边数最大值
const int INF = 0x3f3f3f3f;
int S,V,N,M;
int maxday;
struct Edge{
int to,next,cap,flow;
}edge[MAXM];//注意是MAXM
int tol;
int head[MAXN];
int gap[MAXN],dep[MAXN],pre[MAXN],cur[MAXN];
int aa[555],bb[555],cc[555];
void init(){
tol = 0;
memset(head,-1,sizeof(head));
}
void addedge(int u,int v,int w,int rw=0){
edge[tol].to = v;
edge[tol].cap = w;
edge[tol].next = head[u];
edge[tol].flow = 0;
head[u] = tol++;
edge[tol].to = u;
edge[tol].cap = rw;
edge[tol].next = head[v];
edge[tol].flow = 0;
head[v] = tol++;
}
//最大流开始
int sap(int start,int end,int N){
memset(gap,0,sizeof(gap));
memset(dep,0,sizeof(dep));
memcpy(cur,head,sizeof(head));
int u = start;
pre[u] = -1;
gap[0] = N;
int ans = 0;
while(dep[start] < N){
if(u==end){
int Min = INF;
for(int i=pre[u];i!= -1; i=pre[edge[i^1].to])
if(Min > edge[i].cap - edge[i].flow)
Min = edge[i].cap - edge[i].flow;
for(int i=pre[u];i!=-1;i=pre[edge[i^1].to]){
edge[i].flow += Min;
edge[i^1].flow -=Min;
}
u=start;
ans +=Min;
continue;
}
bool flag = false;
int v;
for(int i= cur[u];i!=-1;i=edge[i].next){
v=edge[i].to;
if(edge[i].cap-edge[i].flow&&dep[v]+1==dep[u]){
flag=true;
cur[u]=pre[v]=i;
break;
}
}
if(flag){
u=v;
continue;
}
int Min = N;
for(int i=head[u];i!= -1;i=edge[i].next)
if(edge[i].cap-edge[i].flow&&dep[edge[i].to]<Min){
Min=dep[edge[i].to];
cur[u] = i;
}
gap[dep[u]]--;
if(!gap[dep[u]]) return ans;
dep[u] = Min +1;
gap[dep[u]]++;
if(u!=start) u = edge[pre[u]^1].to;
}
return ans;
}
//最大流结束
int build(){
int i,j,k,l,m,n;
init();
for(i=1;i<=N;i++){
addedge(S,i,aa[i]);//源点到每个任务的连线为PI
for(j=bb[i];j<=cc[i];j++){
addedge(i,N+j,1); //从这个任务到这个任务开始的时间到结束的时间连一条为1的边
}
}
for(j=1;j<=maxday;j++){
addedge(j+N,V,M);
}
int orz=sap(S,V,V+1);
return orz;
}
bool solve(int su){
int i,j,k;
int ans;
ans = build();
if(ans==su){
printf("Yes\n");
}
else{
printf("No\n");
}
}
int main(){
int T;
int m,n,q,p;
int i,j,k,a,b,c;
int pisum;
scanf("%d",&T);
for(int cas=1;cas<=T;cas++){
scanf("%d%d",&N,&M);
pisum=maxday=0;
for(i=1;i<=N;i++){
scanf("%d%d%d",&aa[i],&bb[i],&cc[i]);
pisum+=aa[i];
maxday=max(maxday,cc[i]);
}
S=0;
V=N+maxday+1;
printf("Case %d: ",cas);
solve(pisum);
puts("");
}
return 0;
}
相关文章推荐
- 初学图论-Kahn拓扑排序算法(Kahn's Topological Sort Algorithm)
- 初学图论-Bellman-Ford单源最短路径算法
- 初学图论-DAG单源最短路径算法
- 初学图论-Dijkstra单源最短路径算法
- 初学图论-Dijkstra单源最短路径算法基于优先级队列(Priority Queue)的实现
- 封装好的Folyd建图,C++源码
- LCA模板
- 图论学习笔记之一——Floyd算法
- 【网络流-最大流-Dinic-建模】POJ3281 Dining:Pascal 解法
- Ford_Fulkerson算法
- 重标记与前移算法
- 【LCA】SPOJ QTREE2
- poj 3249 Test for Job 最长路
- HDU 2544
- 网络流之增广路算法
- Timus 1557 Network Attack DFS+各种各种...
- HDU1289 Tarjan-模板题
- Poj2638 网络流+最短路+二分答案
- Aizu1311 分层图最短路 (...大概)
- Dijkstra算法