hdoj 3572 Task Schedule【最大流】
来源:互联网 发布:java开发接私活 编辑:程序博客网 时间:2024/04/30 02:49
题目:hdoj 3572 Task Schedule
题意:有m台机器和n个任务,然后给出每个任务的开始时间和结束时间以及需要的天数,让你判断有没有这样条件的安排
分析:网络流题目,比较难想到的是把时间区间怎么在图里面建,其实是在这个区间的每个点都连一条边,建图方案。
超级源点s到每个任务 i 连边,容量为第 i 个任务需要的天数,然后每个任务向满足要求的日期连一条容量为1的边,即从开始到结束都连,然后所有日期到汇点连容量m的边,因为每个机器最多同时能够做m个task。
这样建图发现图中的点最多1000个,边非常多,显然是一个稠密图,那么EK算法的复杂度显然不满足,我选择用dinci。
dinci有三个优化,这里一个不能少,否则都会超时。都是深搜里面的技巧,一定注意。
AC代码:
#include <cstdio>#include <cstring>#include <iostream>#include <string>#include <algorithm>#include <vector>#include <queue>using namespace std;#define Del(a,b) memset(a,b,sizeof(a))const int N = 1020;const int inf = 0x3f3f3f3f;int n,m;struct Node{ int from,to,cap,flow;};vector<int> v[N];vector<Node> e;int vis[N]; //构建层次图int cur[N];void add_Node(int from,int to,int cap){ e.push_back((Node){from,to,cap,0}); e.push_back((Node){to,from,0,0}); int tmp=e.size(); v[from].push_back(tmp-2); v[to].push_back(tmp-1);}bool bfs(int s,int t){ Del(vis,-1); queue<int> q; q.push(s); vis[s] = 0; while(!q.empty()) { int x=q.front(); q.pop(); for(int i=0;i<v[x].size();i++) { Node tmp = e[v[x][i]]; if(vis[tmp.to]<0 && tmp.cap>tmp.flow) //第二个条件保证 { vis[tmp.to]=vis[x]+1; q.push(tmp.to); } } } if(vis[t]>0) return true; return false;}int dfs(int o,int f,int t){ if(o==t || f==0) //优化 return f; int a = 0,ans=0; for(int &i=cur[o];i<v[o].size();i++) //注意前面 ’&‘,很重要的优化 { Node &tmp = e[v[o][i]]; if(vis[tmp.to]==(vis[o]+1) && (a = dfs(tmp.to,min(f,tmp.cap-tmp.flow),t))>0) { tmp.flow+=a; e[v[o][i]^1].flow-=a; //存图方式 ans+=a; f-=a; if(f==0) //注意优化 break; } } return ans; //优化}int dinci(int s,int t){ int ans=0; while(bfs(s,t)) { Del(cur,0); int tm=dfs(s,inf,t); ans+=tm; } return ans;}int main(){ //freopen("Input.txt","r",stdin); int T; scanf("%d",&T); for(int cas=1;cas<=T;cas++) { scanf("%d%d",&n,&m); int s=0,ma=0,count=0; for(int i=1;i<=n;i++) { int day,st,en; scanf("%d%d%d",&day,&st,&en); count+=day; add_Node(s,i,day); for(int j=st;j<=en;j++) add_Node(i,n+j,1); ma=max(ma,en); } int t=n+ma+1; for(int i=1;i<=ma;i++) { add_Node(n+i,t,m); } int ans=dinci(s,t); if(ans==count) printf("Case %d: Yes\n",cas); else printf("Case %d: No\n",cas); printf("\n"); for(int i=0;i<=t;i++) v[i].clear(); e.clear(); } return 0;}
0 0
- hdoj 3572 Task Schedule【最大流】
- HDOJ 3572 - Task Schedule 读清题..简单的构图最大流
- hdoj 3572 Task Schedule
- HDOJ-3572 Task Schedule(网络流)
- hdoj 3572 Task Schedule 【最大流 在时间区间建图判断是否满流】
- hdoj Task Schedule 3572 (最大流变型判断是否满流)
- [最大流] 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(最大流)
- linux 下 apache启动、停止、重启命令
- 【算法导论学习-18】queue的数组实现
- 同步的本质 java内存模型 happen before order
- 初始化列表的作用
- 【Unity Shaders】使用CgInclude让你的Shader模块化——Unity内置的CgInclude文件
- hdoj 3572 Task Schedule【最大流】
- HDU 1829 A Bug's Life 并查集
- poj 1491 gcd(求PI的近似值)
- 【坑】在js代码中误用保留关键字
- HDU 1325 Is It A Tree? 并查集
- Linux关机命令详解
- UVa10986_Sending email(最短路)(小白书图论专题)
- JIRA
- memcached-session-manager(MSM) + Tomcat集群session共享