zoukankan      html  css  js  c++  java
  • 最大流任务调度——hdu3572二分图建图

    很简单的任务调度模板题

    把一个工作完成一天的量当做是边

    /*
    任务调度问题最大流 
    因为两个任务之间是没有关系的,两天之间也是没有关系的
    所以抽象成二分图
    任务i在天数[si,ei]之间都连一条双向边,权值为1,表示一天一个任务最多只能完成一个任务点 
    建立超级源点s,和所有的任务连双向边,权值为pi,表示需要pi天来完成任务
    建立超级汇点t,和所有的天数连双向边,权值为m,表示这一天最多完成的任务贡献点
    如果最大流是sum{pi} 就是可行,反之不行 
    */
    #include<bits/stdc++.h>
    using namespace std;
    #define maxn 200005
    #define inf 0x3f3f3f3f
    struct Task{int s,e,p;}u[maxn];
    struct Edge{int to,nxt,w;}e[maxn<<1];
    int head[maxn],T,tot,n,m,w,N,M,s,t;
    void init(){memset(head,-1,sizeof head);tot=0;}
    void add(int u,int v,int w){
        e[tot].to=v;e[tot].w=w;e[tot].nxt=head[u];head[u]=tot++;
    }
    
    int d[maxn];
    bool bfs(){//在残量网络上构造分层图 
        memset(d,0,sizeof d);
        
        queue<int>q;
        while(q.size())q.pop();
        q.push(s);d[s]=1;
        
        while(q.size()){
            int x=q.front();q.pop();
            for(int i=head[x];i!=-1;i=e[i].nxt){
                int y=e[i].to;
                if(d[y] || e[i].w==0)continue;
                q.push(y);
                d[y]=d[x]+1;
                if(y==t)return 1;
            }
        }
        return 0;
    }
    int dinic(int x,int flow){
        if (x==t)return flow;
        int rest=flow;
        for(int i=head[x];i!=-1 && rest>0;i=e[i].nxt){
            int y=e[i].to;
            if(e[i].w==0 || d[y]!=d[x]+1)continue;
            int k=dinic(y,min(rest,e[i].w));
            if(!k)    d[y]=0;    //y点已经被增广完毕,本次dinic时不会再访问这个点
            e[i].w-=k; e[i^1].w+=k;
            rest-=k;
        }
        return flow-rest;
    } 
    
    int main(){
        cin>>T;
        for(int tt=1;tt<=T;tt++){
            init();
            cin>>N>>M;
            int Max=0,sum=0;//最晚完成的天数 
            for(int i=1;i<=N;i++){
                cin>>u[i].p>>u[i].s>>u[i].e;
                Max=max(Max,u[i].e); 
                sum+=u[i].p;
            }
            
            //建图 
            n=Max+N;//点数
            for(int i=1;i<=N;i++){
                for(int j=u[i].s;j<=u[i].e;j++){
                    add(i,j+N,1);add(j+N,i,0);
                }
            }
            s=n+1;t=n+2;
            for(int i=1;i<=N;i++){
                add(s,i,u[i].p);add(i,s,0);
            }
            for(int i=N+1;i<=n;i++){ 
                add(i,t,M);add(t,i,0);
            } 
            
            int flow=0,ans=0;
            while(bfs())
                while(flow=dinic(s,inf))
                    ans+=flow;
            if(ans==sum)
                printf("Case %d: Yes
    ",tt);
            else printf("Case %d: No
    ",tt);
            puts("");
        }
    }
  • 相关阅读:
    2.6 CMMI2级——供应商协议管理(Supplier Agreement Management)
    使用boch仿真器在x86 PC平台上搭建Linux0.11系统环境(windows下)
    java实现登录验证码
    Hadoop DBOutputFormat的使用
    史蒂芬·金《肖申克的救赎》读后感
    Change Base
    IOS深入学习(20)之Object modeling
    android对话框(Dialog)的使用方法
    郝萌主的微信公众号上线了
    Dell shareplex 与HVR数据复制软件
  • 原文地址:https://www.cnblogs.com/zsben991126/p/10988606.html
Copyright © 2011-2022 走看看