Hdu 3572 Task Schedule [最大流] 任务分配,判断满流
来源:互联网 发布:有没有类似知乎的网站 编辑:程序博客网 时间:2024/05/16 22:51
题目意思:
给出 N 件任务和 M台机器, 这N件任务都一个限制: 必须在 [S,E] 之间完成, 而且完成的时间不能超过 P.
一台机器每天只能做意见任务, 不过庆幸的是: 任务是可以拆分的, 比如一件任务要3天完成, 那么你就可以将呀拆分
成3份. 现在问: 在所有机器慢负荷运转的情况下, 如何分配这些任务使得在最后的期限时, 所有任务都能完成.
解题 :
仔细分析下题目不难想到是个网络流模型, 问题就是求源点的流是否能够全部流到汇点. 关键在于构图. 我们选取一个
超级源点和一个超级汇点, 一开始把源点指向所有的任务, 边权就是完成这件任务需要的天数, 然后按照完成这件任务
的时间区间, 将任务分成 E-S+1份, 意思就是在这几天中每天都可以完成这件任务的一份.这样, 就可以在任务和能够完
成它的这些天之间连边, 边权为1, 因为每次只能做一份, 最后在所有的天和汇点之间连边, 边权为M, 表示每一天, M台
机器可以完成M份工作:
#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 ([最大流]任务分配,判断满流)
- hdu3572 Task Schedule(基础) [最大流]任务分配,判断满流
- HDU3572Task Schedule(任务分配/最大流判断满流)
- hdu 3572 Task Schedule(最大流,判断满流+isap模版)
- [最大流] hdu 3572 Task Schedule
- hdu 3572 Task Schedule IPSA 最大流
- HDU 3572 Task Schedule(最大流)
- 【最大流】 HDU 3572 Task Schedule
- hdu 3572 Task Schedule 【网络最大流】
- hdu 3572 Task Schedule(最大流)
- HDU - 3572 Task Schedule (最大流)
- hdu 3572 Task Schedule(最大流)
- HDU 3572 Task Schedule(最大流)
- [HDU 3572]Task Schedule[最大流]
- hdu 3572 Task Schedule(最大流)
- HDU 3572 Task Schedule(最大流)
- hdu 3572 Task Schedule hdu 2883 kebab 最大流
- WEB漏洞挖掘技术
- Android计时器Chronometer的使用
- 使用Gallery实现缩略图浏览器
- PeopleSoft 数据库 VS Oracle 数据库
- Android模拟器访问本机本地地址
- Hdu 3572 Task Schedule [最大流] 任务分配,判断满流
- 数据库查询
- Android开发中的UI事件监听处理机制总结
- 正则表达式
- ZOJ1204
- PPPoE验证与利用
- Android界面布局(Layout)和菜单(Menu)
- Android中UI视图之试图绘制机制
- Mysql触发器详解