[最大流] hdu 3572 Task Schedule

来源:互联网 发布:北航软件工程硕士 编辑:程序博客网 时间:2024/04/30 02:51

题目链接点击打开链接

将所有任务和每一天都当作一个节点,通过如下规则可构成网络:

1.设一个源点S与所有任务节点n1...n2......nn相连,每一条弧的容量为完成任务所需要的天数。

2.如果第i个任务可以在第Si天开始,在第Ei天结束,则将Si到Ei间的每一天的节点,都与第i个任务节点相连接,弧的容量为1。

3.最后,将所有的日期节点,与一个汇点相连,所有的弧的容量都为机器的数量M。

如此构成的网络中,如果所有任务完成需要的总天数(P1+P2...Pn)和最大流相等,则所有任务都可以在规定时间内完成。


最大流Dinic算法代码:

#include<iostream>#include<cstdio>#include<cstring>#include<vector>#include<queue>#define INF 0x7fffffff#define maxn 25000using namespace std;struct Edge{    int from,to,cap,flow;};class Dinic{private:    int s,t,c;    vector<Edge>edges;    vector<int>G[maxn];    bool vis[maxn];    int dist[maxn];    int cur[maxn];public:    int n,m;    void AddEdge(int from,int to,int cap){        edges.push_back((Edge){from,to,cap,0});        edges.push_back((Edge){to,from,0,0});        c=edges.size();        G[from].push_back(c-2);        G[to].push_back(c-1);    }    bool BFS(){        queue<int>Q;        memset(vis,0,sizeof(vis));        Q.push(s);        dist[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;                    dist[e.to]=dist[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(dist[x]+1==dist[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);            flow+=DFS(s,INF);        }        return flow;    }    void init(){        edges.clear();        for(int i=0;i<maxn;i++){            G[i].clear();            dist[i]=0;        }    }}Do;int main(){    int t;    cin>>t;    for(int k=1;k<=t;k++){        Do.init();int MaxE=0,SumP=0;        scanf("%d%d",&Do.n,&Do.m);        for(int i=1;i<=Do.n;i++){            int P,S,E;            cin>>P>>S>>E;            SumP+=P;            if(E>MaxE)MaxE=E;            Do.AddEdge(0,i,P);            for(int j=S;j<=E;j++){                Do.AddEdge(i,Do.n+j,1);            }        }        for(int j=Do.n+1;j<=Do.n+MaxE;j++){            Do.AddEdge(j,MaxE+Do.n+1,Do.m);        }        if(Do.Maxflow(0,MaxE+Do.n+1)==SumP)cout<<"Case "<<k<<": Yes"<<endl;        else cout<<"Case "<<k<<": No"<<endl;        cout<<endl;    }    return 0;}


0 0
原创粉丝点击