zoukankan      html  css  js  c++  java
  • 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
    
    ", k );
    		}
    		else{
    			printf( "Case %d: No
    
    ", k );
    		}
    	}
    	return 0;
    }  





  • 相关阅读:
    为什么不能获取PHP表单变量的?
    DOM4j读写XML(实例)
    MyEclipse环境的使用中的一些常识
    Springcloud学习笔记38springboot整合日志框架log4j2
    Springcloud学习笔记37任务调度框架Quartz 使用(Cron表达式)与@scheduled注解定时任务
    Linux学习笔记05linux 常用操作命令02(touch命令、cp命令、rm命令、mv命令)
    Linux学习笔记07Vim文本编辑器
    Java基础知识13Java反射原理以及基本使用和重写与重载的区别
    Linux学习笔记07常用操作命令(tar命令)
    Java基础知识14commonsio第3方开源库的具体使用(IOUtils类、FileUtils类、FilenameUtils类)
  • 原文地址:https://www.cnblogs.com/lcchuguo/p/5077973.html
Copyright © 2011-2022 走看看