hdu3572Task Schedule 最大流
2015-08-10 20:58
232 查看
//n个任务,m台机器
//每个任务都有开始工作的时间,结束的时间和需要一台机器工作的天数
//每个任务的工作可以断开,只需要在规定的时间内用机器工作规定天数
//在同一天,一个任务只能被一台机器工作
//问能否安排时间使得所有的任务都能在规定时间内完成
//对任务和其工作的时间建立权值为1的边
//在建立一个超级源点和一个超级汇点
//从源点向任务引入权值为该任务需要工作的天数,从每一天向汇点建立权值为m的边
//这样从源点到汇点的最大流如果大于所有的任务的需要工作的天数之和,所有任务就能在规定时间完成
dinic算法:
isap算法:
//每个任务都有开始工作的时间,结束的时间和需要一台机器工作的天数
//每个任务的工作可以断开,只需要在规定的时间内用机器工作规定天数
//在同一天,一个任务只能被一台机器工作
//问能否安排时间使得所有的任务都能在规定时间内完成
//对任务和其工作的时间建立权值为1的边
//在建立一个超级源点和一个超级汇点
//从源点向任务引入权值为该任务需要工作的天数,从每一天向汇点建立权值为m的边
//这样从源点到汇点的最大流如果大于所有的任务的需要工作的天数之和,所有任务就能在规定时间完成
dinic算法:
#include<cstdio> #include<cstring> #include<iostream> #include<queue> using namespace std ; const int maxn = 10010 ; const int inf = 0x7fffffff ; int st = 0 ;int en = 1001 ; int dis[maxn]; struct Edge { int v ;int next; int w ; }edge[maxn*maxn] ; int head[maxn] , nedge ; void addedge(int u , int v , int w) { edge[nedge].v = v ; edge[nedge].w = w ; edge[nedge].next = head[u] ; head[u] = nedge++ ; edge[nedge].v = u ; edge[nedge].w = 0 ; edge[nedge].next = head[v] ; head[v] = nedge++ ; } bool bfs() { queue<int> que ; memset(dis , -1 ,sizeof(dis)) ; dis[st] = 0 ; que.push(st) ; while(que.size()) { int u = que.front() ; que.pop() ; for(int i = head[u]; i != -1 ; i = edge[i].next) { int v = edge[i].v ; if(edge[i].w > 0 && dis[v] < 0) { dis[v] = dis[u] + 1 ; que.push(v) ; } } } if(dis[en] > 0) return true ; return false ; } int dfs(int x,int mx) { if(x==en) return mx; int i; int ans=0; int a; for(i=head[x];i!=-1;i=edge[i].next) { int v=edge[i].v; if(dis[v]==dis[x]+1&&edge[i].w>0&&(a=dfs(v,min(mx,edge[i].w)))) { edge[i].w -= a; edge[i^1].w += a; ans += a; mx -= a; if(!mx) break; } } if(!ans) dis[x] = -1; //dinic算法的主要优化 return ans; } int main() { //freopen("in.txt" , "r" ,stdin) ; int t ; int cas = 0 ; int n , m ; scanf("%d" , &t) ; while(t--) { scanf("%d%d" , &n , &m) ; int sum = 0 ; memset(head ,-1 , sizeof(head)) ; nedge = 0 ; int ma = 0 ;int mi = inf ; for(int i = 1;i <= n;i++) { int si , ei , pi ; scanf("%d%d%d" ,&pi , &si , &ei) ; addedge(st , i , pi) ; sum += pi ; for(int j = si;j <= ei ;j++) addedge(i , j + 500, 1) ; } for(int j = 501 ;j <= 1000;j++) addedge(j , en , m) ; int res ;int ans = 0 ; while(bfs()) while(res = dfs(st , inf)) ans += res ; printf("Case %d: ",++cas) ; if(ans >= sum) puts("Yes") ; else puts("No"); puts("") ; } return 0 ; }
isap算法:
#include<cstdio> #include<cstring> #include<iostream> #include<queue> using namespace std ; const int maxn = 10010 ; const int inf = 0x7fffffff ; int st = 0 ;int en = 1001 ; int n , m ; int dis[maxn];int gap[maxn] ,cur[maxn],pre[maxn] ; struct Edge { int v ;int next; int w ; }edge[maxn*maxn] ; int head[maxn] , nedge ; void addedge(int u , int v , int w) { edge[nedge].v = v ; edge[nedge].w = w ; edge[nedge].next = head[u] ; head[u] = nedge++ ; edge[nedge].v = u ; edge[nedge].w = 0 ; edge[nedge].next = head[v] ; head[v] = nedge++ ; } void bfs() { memset(dis, -1 , sizeof(dis)) ; memset(gap , 0 , sizeof(gap)) ; queue<int> que ; dis[en] = 0 ; gap[0]++ ; que.push(en) ; while(que.size()) { int u = que.front() ;que.pop() ; for(int i = head[u] ; i != -1 ;i = edge[i].next) { int v = edge[i].v ; if(dis[v] < 0 && edge[i^1].w > 0) { dis[v] = dis[u] + 1 ; gap[dis[v]]++ ; que.push(v) ; } } } } int isap() { bfs() ; memset(pre , -1 , sizeof(pre)) ; memcpy(cur , head, sizeof(head)) ; int u = pre[st] = st ; gap[0] = n ; int maxflow =0 ; int aug = inf ;bool flag ; while(dis[st] < n) { flag = false ; for(int i = cur[u] ;i != -1 ;i = edge[i].next) { int v = edge[i].v ; if(dis[u] == dis[v] + 1 && edge[i].w > 0) { flag = true ; cur[u] = i ; pre[v] = u ; u = v ; aug = min(aug , edge[i].w) ; if(v == en) { maxflow += aug ; for(u = pre[v] ; ; u = pre[u]) { edge[cur[u]].w -= aug ; edge[cur[u]^1].w += aug ; if(u == st)break; } aug = inf ; } break ; } } if(flag)continue ; int mi = n; for(int i=head[u];i!=-1;i=edge[i].next) { int v=edge[i].v; if(dis[v] < mi && edge[i].w > 0) { mi=dis[v]; cur[u]=i; } } if((--gap[dis[u]]) == 0)break ; dis[u] = mi + 1 ; gap[dis[u]]++ ; u = pre[u] ; } return maxflow ; } int main() { // freopen("in.txt" , "r" ,stdin) ; int t ; int cas = 0 ; scanf("%d" , &t) ; while(t--) { scanf("%d%d" , &n , &m) ; int sum = 0 ; memset(head ,-1 , sizeof(head)) ; nedge = 0 ; int ma = 0 ;int mi = inf ; for(int i = 1;i <= n;i++) { int si , ei , pi ; scanf("%d%d%d" ,&pi , &si , &ei) ; addedge(st , i , pi) ; sum += pi ; for(int j = si;j <= ei ;j++) addedge(i , j + 500, 1) ; } for(int j = 501 ;j <= 1000;j++) addedge(j , en , m) ; int res ;int ans = 0 ; n = n + 2 + 500 ; ans = isap() ; printf("Case %d: ",++cas) ; if(ans >= sum) puts("Yes") ; else puts("No"); puts("") ; } return 0 ; }
相关文章推荐
- 页面定时跳转(倒计时跳转)代码总结
- POJ 开关问题 1830【高斯消元求矩阵的秩】
- 数据库日常维护-CheckList_02有关数据库备份检查
- 常见的攻击方式详解
- (2)PHP运行时的全局参数
- hdu 1003
- python基础教程学习笔记 — 准备Windows下开发环境
- 并发网络编程学习之路(二):多进程与进程池(续)
- 【动态树问题】LCT学习笔记
- android 实现QQ好友分享和QQ空间分享
- C语言-07-预处理、typedef、static和extern
- H5视频播放自动全屏,暂停退出全屏等功能
- DB2分区表删除和添加分区
- (剑指Offer)面试题59:对称的二叉树
- Advanced Fruits (LCS+递归、模板)
- 我的Android进阶之旅------>HTTP Content-type 对照表
- HUD 1564 Play a game【博弈论】
- python:5、函数2
- hdu-2116-Has the sum exceeded
- 简单区分Vmware的三种网络连接模式(bridged、NAT、host-only)