您的位置:首页 > 理论基础 > 计算机网络

HDU 3572 最大流

2015-11-07 20:58 441 查看
最近在刷题和各种事情,忘记更新了,最近会把做的题目都更新出来


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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  网络流 最大流 图论