Hdu 3572 Task Schedule [最大流] 任务分配,判断满流
2012-09-04 23:48
302 查看
题目意思:
给出 N 件任务和 M台机器, 这N件任务都一个限制: 必须在 [S,E] 之间完成, 而且完成的时间不能超过 P.
一台机器每天只能做意见任务, 不过庆幸的是: 任务是可以拆分的, 比如一件任务要3天完成, 那么你就可以将呀拆分
成3份. 现在问: 在所有机器慢负荷运转的情况下, 如何分配这些任务使得在最后的期限时, 所有任务都能完成.
解题 :
仔细分析下题目不难想到是个网络流模型, 问题就是求源点的流是否能够全部流到汇点. 关键在于构图. 我们选取一个
超级源点和一个超级汇点, 一开始把源点指向所有的任务, 边权就是完成这件任务需要的天数, 然后按照完成这件任务
的时间区间, 将任务分成 E-S+1份, 意思就是在这几天中每天都可以完成这件任务的一份.这样, 就可以在任务和能够完
成它的这些天之间连边, 边权为1, 因为每次只能做一份, 最后在所有的天和汇点之间连边, 边权为M, 表示每一天, M台
机器可以完成M份工作:
![](http://img.my.csdn.net/uploads/201209/04/1346773841_6116.png)
给出 N 件任务和 M台机器, 这N件任务都一个限制: 必须在 [S,E] 之间完成, 而且完成的时间不能超过 P.
一台机器每天只能做意见任务, 不过庆幸的是: 任务是可以拆分的, 比如一件任务要3天完成, 那么你就可以将呀拆分
成3份. 现在问: 在所有机器慢负荷运转的情况下, 如何分配这些任务使得在最后的期限时, 所有任务都能完成.
解题 :
仔细分析下题目不难想到是个网络流模型, 问题就是求源点的流是否能够全部流到汇点. 关键在于构图. 我们选取一个
超级源点和一个超级汇点, 一开始把源点指向所有的任务, 边权就是完成这件任务需要的天数, 然后按照完成这件任务
的时间区间, 将任务分成 E-S+1份, 意思就是在这几天中每天都可以完成这件任务的一份.这样, 就可以在任务和能够完
成它的这些天之间连边, 边权为1, 因为每次只能做一份, 最后在所有的天和汇点之间连边, 边权为M, 表示每一天, M台
机器可以完成M份工作:
![](http://img.my.csdn.net/uploads/201209/04/1346773841_6116.png)
#include<iostream> #include<cmath> #include<cstring> using namespace std; #define MAXN 500 #define MAXE 500002 #define INF 0x7ffffff int ne,nv,tmp,s,t,index; struct Edge{ int next,pair; int v,cap,fLow; }edge[MAXE]; int net[MAXN]; int maxday; int ISAP() { int numb[MAXN],dist[MAXN],curedge[MAXN],pre[MAXN]; int cur_fLow,max_fLow,u,tmp,neck,i; memset(dist,0,sizeof(dist)); memset(numb,0,sizeof(numb)); memset(pre,-1,sizeof(pre)); for(i = 1 ; i <= nv ; ++i) curedge[i] = net[i]; numb[nv] = nv; max_fLow = 0; u = s; while(dist[s] < nv) { if(u == t) { cur_fLow = INF; for(i = s; i != t;i = edge[curedge[i]].v) { if(cur_fLow > edge[curedge[i]].cap) { neck = i; cur_fLow = edge[curedge[i]].cap; } } for(i = s; i != t; i = edge[curedge[i]].v) { tmp = curedge[i]; edge[tmp].cap -= cur_fLow; edge[tmp].fLow += cur_fLow; tmp = edge[tmp].pair; edge[tmp].cap += cur_fLow; edge[tmp].fLow -= cur_fLow; } max_fLow += cur_fLow; u = neck; } /* if .... eLse ... */ for(i = curedge[u]; i != -1; i = edge[i].next) if(edge[i].cap > 0 && dist[u] == dist[edge[i].v]+1) break; if(i != -1) { curedge[u] = i; pre[edge[i].v] = u; u = edge[i].v; }else{ if(0 == --numb[dist[u]]) break; curedge[u] = net[u]; for(tmp = nv,i = net[u]; i != -1; i = edge[i].next) if(edge[i].cap > 0) tmp = tmp<dist[edge[i].v]?tmp:dist[edge[i].v]; dist[u] = tmp + 1; ++numb[dist[u]]; if(u != s) u = pre[u]; } } return max_fLow; } void addedge(int u,int v,int f) { edge[index].next = net[u]; edge[index].v = v; edge[index].cap = f; edge[index].fLow = 0; edge[index].pair = index+1; net[u] = index++; edge[index].next = net[v]; edge[index].v = u; edge[index].cap = 0; edge[index].fLow = 0; edge[index].pair = index-1; net[v] = index++; } int main() { int i,j,np,nc,m,n; int a,b,d,k,vaL; int tt; scanf("%d",&tt); for(int cas=1;cas<=tt;++cas) { int cases=1; int maxval=0; maxday=0; scanf("%d%d",&n,&m); index=0;//index从0开始扫 s = 0; t = 0; memset(net,-1,sizeof(net)); for(i=1;i<=n;i++) { int pi,si,ei; scanf("%d%d%d",&pi,&si,&ei); maxday=max(maxday,ei); maxval+=pi; addedge(s,i,pi); for(j=si;j<=ei;j++) addedge(i,n+j,1); } t=n+maxday+1; nv=t+1; for(i=1;i<=maxday;i++) addedge(i+n,t,m); int ans=ISAP(); if (ans == maxval) printf("Case %d: Yes\n\n", cas); else printf("Case %d: No\n\n", cas); } return 0; }
相关文章推荐
- HDU 3572 Task Schedule ([最大流]任务分配,判断满流)
- HDU--杭电--3572--Task Schedule--最大流
- hdoj 3572 Task Schedule 【最大流 在时间区间建图判断是否满流】
- hdu 3572 Task Schedule 【网络最大流】
- HDU3572Task Schedule(任务分配/最大流判断满流)
- HDU 3572 Task Schedule 网络流 ISAP
- HDU3572——Task Schedule (最大流判断满流)
- hdu 3572 : Task Schedule (网络流)
- HDU 3572 Task Schedule
- Task Schedule HDU - 3572
- hdu 3572 Task Schedule 网络流
- HDU 3572 Task Schedule(最大流判断满流)
- hdu 3572 Task Schedule 网络流
- hdu 3572 Task Schedule【网络流建图应用】
- hdu3572 任务分配/最大流判断满流
- hdu 3572 Task Schedule(最大流,判断满流+isap模版)
- hdu3572 Task Schedule(基础) [最大流]任务分配,判断满流
- hdu3572 任务分配/最大流判断满流
- HDU 3572(Task Schedule) ISAP做法
- Task Schedule HDU - 3572 + Alice's Chance POJ - 1698