hdu 3572 Task Schedule

        题意:有m个机器,n个任务,每个任务在同一时刻只能被一台机器执行,机器在没执行完任务时可以更换任务。每个任务有需要的时间,最早开始时间和最晚结束时间,问这些任务是否能完成。

        思路:最大流。建图:源1到源2,容量正无穷;源2到500个时间段,容量为机器数。对每个任务,从最早开始时间到最晚结束时间各引出一条容量为1的边,然后连边到汇,容量为任务需要的时间。跑一下最大流即可。


#include<iostream>
#include<cmath>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<string.h>
#include<cstdio>


using namespace std;

#define maxn 1010
#define INF 1000000000

struct Edge{          
    int u; int v;          
    int cap; int flow;          
    Edge(int u,int v,int c):u(u),v(v),cap(c),flow(0){}            
    Edge(){};          
};          
Edge edges[maxn*maxn];        
          
int ne;          
int head[maxn];          
int next[maxn*maxn];          
int n,m;     
int L[maxn*maxn];     
int D[maxn];     
    
void init(){          
    memset(head,-1,sizeof(head));       
    memset(D,0,sizeof(D));       
    ne=0;          
}          
    
int lv[maxn];          
bool bfs(int s,int t){          
    memset(lv,-1,sizeof(lv)); lv[s]=0;          
    queue<int> que; que.push(s);           
    while(!que.empty()){          
        int cur=que.front(); que.pop();          
        for(int i=head[cur];i!=-1;i=next[i]){          
            Edge& e=edges[i];          
            if(lv[e.v]!=-1)continue;          
            if(e.flow<e.cap){          
                lv[e.v]=lv[cur]+1;          
                que.push(e.v);          
            }          
        }          
        if(lv[t]!=-1)return 1;          
    }          
    return 0;          
}          
    
int cur[maxn];    
int dfs(int x,int a){          
    if(x==1002||a==0)return a;
    int re=0;          
    for(int& i=cur[x];i!=-1;i=next[i]){          
        Edge& e=edges[i];          
        int t;          
        if(lv[e.v]==(lv[x]+1)&& (t=dfs( e.v , min(a,e.cap-e.flow))) ){          
            edges[i].flow+=t;          
            edges[i^1].flow-=t;          
            re+=t;          
            a-=t;          
            if(a==0)break;          
        }          
    }          
    return re;          
}    
    
int maxflow(int s,int t){          
    int flow=0;          
    while(bfs(s,t)){    
        memcpy(cur,head,sizeof(head));          
        flow+=dfs(s,INF);      
    }          
    return flow;          
}    
    
void addedge(int u,int v,int c){          
    edges[ne]=Edge(u,v,c);            
    next[ne]=head[u];          
    head[u]=ne;          
    ne++;        
    edges[ne]=Edge(v,u,0);          
    next[ne]=head[v];          
    head[v]=ne;          
    ne++;          
}      

int main(){
	int t;
	cin>>t;
	for(int cas=1;cas<=t;cas++){
		init();
		int N,M;
		scanf("%d%d",&N,&M);
		
		addedge(1001,0,1000000000);
		
		for(int i=1;i<=500;i++){
			addedge(0,i,M);
		}
		
		int sum=0;
		for(int i=1;i<=N;i++){
			int p,s,e;
			scanf("%d%d%d",&p,&s,&e);
			for(int j=s;j<=e;j++){
				addedge(j,500+i,1);
			}
			addedge(500+i,1002,p);
			sum+=p;
		}
		
		int mf=maxflow(1001,1002);
		if(sum==mf){
			printf("Case %d: Yes\n",cas);
		}else{
			printf("Case %d: No\n",cas);
		}
		printf("\n");
	}
	return 0;
} 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值