Task Schedule

点击打开链接

题意:某个工厂有M台机器,需要完成N项任务。给出每项任务的完成时间PI,开始时间SI,结束时间EI;现在问你能否在刚好完成(一次);

解析:以时间为单元构图,即将完成某一任务 I ,所需要时间PI,拆分成PI个单元1.然后设置源点s( 0 )和终点t( n + maxday + 1 ).那么从源点到完成第i个任务则其权值为完成当前任务所需要的时间PI。然后从当前任务 i 与其完成的时段SI ~ EI 赋值为1( 每天一台机器,所以完成的是1个单元,从而进行连通)。同理,有M台机器,因此,到达终点的权值为M,即1 * M;

然后使用最大流即可。

#include <fstream>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>

using namespace std;

const int MAXN = 100010;//点数最大值
const int MAXM = 400010;//边数最大值
const int INF = 0x3f3f3f3f; 

struct Edge {
    int to,next,cap,flow;
}edge[MAXM];//注意是MAXN
int tol;
int head[MAXN];
int gap[MAXN],dep[MAXN],cur[MAXN]; 

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].flow = 0;
	edge[tol].next = head[u];
	head[u] = tol++;
	edge[tol].to = u;
	edge[tol].cap = rw;
	edge[tol].flow = 0;
	edge[tol].next = head[v];
	head[v] = tol++;
} 

int Q[MAXN];
void BFS(int start,int end) {
	memset(dep,-1,sizeof(dep));
	memset(gap,0,sizeof(gap));
	gap[0] = 1;
	int front = 0, rear = 0;
	dep[end] = 0;
	Q[rear++] = end;
	while(front != rear) {
		int u = Q[front++];
		for(int i = head[u]; i != -1; i = edge[i].next)
		{
			int v = edge[i].to;
			if(dep[v] != -1)continue;
			Q[rear++] = v;
			dep[v] = dep[u] + 1;
			gap[dep[v]]++;
		}
	}
} 

int S[MAXN];
int sap(int start,int end,int N) {
	BFS(start,end);
	memcpy(cur,head,sizeof(head));
	int top = 0;
	int u = start;
	int ans = 0;
	while(dep[start] < N)
	{
		if(u == end)
		{
			int Min = INF;
			int inser;
			for(int i = 0;i < top;i++)
				if(Min > edge[S[i]].cap - edge[S[i]].flow)
				{
					Min = edge[S[i]].cap - edge[S[i]].flow;
					inser = i;
                }
				for(int i = 0;i < top;i++)
				{
					edge[S[i]].flow += Min;
					edge[S[i]^1].flow -= Min;
				}
				ans += Min;
				top = inser;
				u = edge[S[top]^1].to;
				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] = i;
				break;
			}
		}
		if(flag)
		{
			S[top++] = cur[u];
			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[S[--top]^1].to;
		}
	return ans;
}
/*最大流模板*/

int main(){
	int Case;
	int n, m;
	scanf( "%d", &Case );
	for( int k = 1; k <= Case; ++k ){
		scanf( "%d%d", &n, &m );
		init();
		int value, start, end, s = 0, e = 0,sum = 0, Max = 0;
		for( int i = 1; i <= n; ++i ){
			scanf( "%d%d%d", &value, &start, &end );
			Max = max( Max, end );
			sum += value;
			addedge( s, i, value );
			for( int j = start; j <= end; ++j ){
				addedge( i, n + j, 1 );
			}
		}
		int N = n + 1 + Max;
		for( int i = 1; i <= Max; ++i ){
			addedge( i + n, N, m );
		}
		int ans = sap( s, N, N);
		if( ans == sum ){
			printf( "Case %d: Yes\n\n", k );
		}
		else{
			printf( "Case %d: No\n\n", k );
		}
	}
	return 0;
}  

Task Schedule,布布扣,bubuko.com

时间: 2024-08-04 13:10:24

Task Schedule的相关文章

hdu 3572 Task Schedule

Task Schedule 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

Task Schedule(Hdu3572网络流)

跟着风神学图论 Task Schedule(Hdu3572网络流) 题意: 有一个工厂最近新近了一批机器人,这些机器人被用来解决若干个任务.每个任务都有完成所需的时间pi和规定了必须在si天或者si天之后才能处理这个任务,且需要在ei天之内完成. 工厂规定每个机器人每天只能处理一个任务,且每个任务最多只能由一个机器处理. 问这些机器人能否在顺利完成这些任务. 题解: 网络流建模. 对于每一个任务来说,它必须要在si到ei天之间被处理. 并且要在pi天以内完成. 所以我们可以把每一天当成点来考虑,

bestcoder#3——Task schedule

Task schedule Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 0    Accepted Submission(s): 0 Problem Description 有一台机器,并且给你这台机器的工作表,工作表上有n个任务,机器在ti时间执行第i个任务,1秒即可完成1个任务.有m个询问,每个询问有一个数字q,表示如果在q时间

HDU 4907 (杭电BC#3 1001)Task schedule(水)

题目地址:HDU 4907 水题...不多说..哈希后从后往前遍历一遍就行了. 代码如下: #include <iostream> #include <stdio.h> #include <string.h> #include <stdlib.h> #include <math.h> #include <ctype.h> #include <queue> #include <map> #include<a

HDU 4907 BestCoder3_1 Task schedule

Task schedule Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 0    Accepted Submission(s): 0 Problem Description 有一台机器,并且给你这台机器的工作表,工作表上有n个任务,机器在ti时间执行第i个任务,1秒即可完成1个任务.有m个询问,每个询问有一个数字q,表示如果在q时间

HDU 3572 Task Schedule(ISAP)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3572 题意:m台机器,需要做n个任务.第i个任务,你需要使用机器Pi天,且这个任务要在[Si  ,  Ei]区间内完成才有效.对于一个任务,只能由一个机器来完成,一个机器同一时间只能做一个任务.当然,一个任务可以分成几段不连续的时间来完成.问,能否做完全部任务. 题意很清晰,也就是判断是否是满流. 对于网络流问题,模板大家都有,关键在于如何建图(详见资料) 思路:今天问了龙哥,对建图有了一定的了解,

hdu 3572 Task Schedule(最大流)

hdu 3572 Task Schedule 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 tas

hdoj 3572 Task Schedule【最大流】

题目:hdoj 3572 Task Schedule 题意:有m台机器和n个任务,然后给出每个任务的开始时间和结束时间以及需要的天数,让你判断有没有这样条件的安排 分析:网络流题目,比较难想到的是把时间区间怎么在图里面建,其实是在这个区间的每个点都连一条边,建图方案. 超级源点s到每个任务 i 连边,容量为第 i 个任务需要的天数,然后每个任务向满足要求的日期连一条容量为1的边,即从开始到结束都连,然后所有日期到汇点连容量m的边,因为每个机器最多同时能够做m个task. 这样建图发现图中的点最多

HDU3572 Task Schedule 【最大流】

Task Schedule Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 4003    Accepted Submission(s): 1347 Problem Description Our geometry princess XMM has stoped her study in computational geometry t