hdu 3572 Task Schedule(多源多汇)
2015-07-23 10:29
323 查看
建图:多源多汇问题,大白书算法通过体添加超汇和超源
把每个任务和每一天都看做一个点,添加源点和汇点。
源点与每个任务之间连一条边,容量为完成该任务所需处理次数。
若第i个任务可以在Si至Ei天处理,则由该任务向这些天分别连一条边,容量为1,表示此任务每天只能被处理一次。
最后,从每一天连一条到汇点的边,容量为机器数M,表示每天可以处理M个任务。
若求出的最大流等于所有任务需要处理的次数之和,说明能完成任务;否则,不能完成任务。
dinic算法
注意:初始化的时候可能把0连接的边给忘掉
把每个任务和每一天都看做一个点,添加源点和汇点。
源点与每个任务之间连一条边,容量为完成该任务所需处理次数。
若第i个任务可以在Si至Ei天处理,则由该任务向这些天分别连一条边,容量为1,表示此任务每天只能被处理一次。
最后,从每一天连一条到汇点的边,容量为机器数M,表示每天可以处理M个任务。
若求出的最大流等于所有任务需要处理的次数之和,说明能完成任务;否则,不能完成任务。
dinic算法
注意:初始化的时候可能把0连接的边给忘掉
[code]#include <vector> #include <cstring> #include <algorithm> #include <cstdio> #include <queue> using namespace std; #define maxn 1100 #define INF 0x7f7f7f7f struct Edge { int from,to,cap,flow; }; struct Dinic { int n,m,s,t; vector<Edge>edges; vector<int>G[maxn]; bool vis[maxn]; int d[maxn]; int cur[maxn]; void addEdge(int from,int to,int cap) { edges.push_back((Edge) {from,to,cap,0}); edges.push_back((Edge) {to,from,0,0}); m=edges.size(); G[from].push_back(m-2); G[to].push_back(m-1); } void init(){ edges.clear(); for(int i=0;i<=maxn;i++) G[i].clear(); } bool Bfs() { memset(vis,0,sizeof(vis)); queue<int>Q; while(!Q.empty()) Q.pop(); Q.push(s); d[s]=0; vis[s] = 1; while(!Q.empty()) { int x = Q.front(); Q.pop(); for(int i=0; i<G[x].size(); i++) { Edge& e = edges[G[x][i]]; if(!vis[e.to]&&e.cap>e.flow) { vis[e.to] = 1; d[e.to] = d[x]+1; Q.push(e.to); } } } return vis[t]; } int dfs(int x,int a) { if(x==t||a==0) return a; int flow = 0,f; for(int &i=cur[x]; i<G[x].size(); i++) { Edge& e = edges[G[x][i]]; if(d[x]+1==d[e.to]&&(f=dfs(e.to,min(a,e.cap-e.flow)))>0) { e.flow += f; edges[G[x][i]^1].flow -= f; flow += f; a -= f; if(a==0) break; } } return flow; } int maxflow(int s,int t) { this->s=s; this->t=t; int flow = 0; while(Bfs()) { memset(cur,0,sizeof(cur)); flow+=dfs(s,INF); } return flow; } }; int main(){ int T; int n,k; Dinic slove; int cas = 0; scanf("%d",&T); while(T--){ scanf("%d%d",&n,&k); slove.init(); int sum = 0; int mx = -1; for(int i=1;i<=n;i++){ int x,y,z; scanf("%d%d%d",&x,&y,&z); sum+=x; slove.addEdge(0,i,x); if(mx<z) mx = z; for(int j=y;j<=z;j++){ slove.addEdge(i,n+j,1); } } int ss=0,tt=mx+n+1; for(int j=1;j<=mx;j++) { slove.addEdge(j+n,tt,k); } printf("Case %d: ",++cas); printf(slove.maxflow(ss,tt)==sum?"Yes\n\n":"No\n\n"); } }
相关文章推荐
- webapp 开发 ---- phonegap 环境搭建
- 在Hadoop2.2.0上运行Wordcount小程序
- iOS navigationBar颜色
- android单元测试
- iOS 7的手势滑动返回
- Linux -- 是一个操作系统,1991年由linus Torvalds发布的,核心是kernel版本号
- Android 保持亮屏
- OFBiz + Opentaps 目录管理 一. 基本概念
- 设立sql语句在控制台的输出
- BP算法代价函数的偏导数
- zoj 3469 Food Delivery (区间dp)
- fedaro关于mysql的编译问题
- Eclipse常用快捷键
- Java大数练习第二弹
- HTML5引擎Construct2技术剖析(一)
- 修改webView的背景色
- Java大数练习第二弹
- setWillNotDraw(false);
- RHEL6设置本地YUM源
- 读书笔记MoreEffectiveC++(三)