设为首页 加入收藏

TOP

hdu3572Task Schedule 最大流
2015-11-21 00:55:31 来源: 作者: 【 】 浏览:1
Tags:hdu3572Task Schedule 最大

//n个任务,m台机器
//每个任务都有开始工作的时间,结束的时间和需要一台机器工作的天数
//每个任务的工作可以断开,只需要在规定的时间内用机器工作规定天数
//在同一天,一个任务只能被一台机器工作
//问能否安排时间使得所有的任务都能在规定时间内完成
//对任务和其工作的时间建立权值为1的边
//在建立一个超级源点和一个超级汇点
//从源点向任务引入权值为该任务需要工作的天数,从每一天向汇点建立权值为m的边
//这样从源点到汇点的最大流如果大于所有的任务的需要工作的天数之和,所有任务就能在规定时间完成
dinic算法:

#include
   
     #include
    
      #include
     
       #include
      
        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
       
         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
   
     #include
    
      #include
     
       #include
      
        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
       
         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 ; } 
       
      
     
    
   

?

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇hdu 2602 - Bone Collector(01背.. 下一篇hdu-2116-Has the sum exceeded

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: