码迷,mamicode.com
首页 > 其他好文 > 详细

Task Schedule

时间:2014-07-17 19:11:03      阅读:273      评论:0      收藏:0      [点我收藏+]

标签:最大流

点击打开链接

题意:某个工厂有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

Task Schedule

标签:最大流

原文地址:http://blog.csdn.net/bo_jwolf/article/details/37909747

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!