网络流基础模型——任务分配模型(HDU 3572)

题目链接

题解思路:先构建一个超级原点0,由原点连向n个任务,每条边的流量为p[i],然后有每个任务连向他们自身的时间点s[i]->e[i],每条边的流量为1,最后再由时间点连向超级终点,每条边流量为m(机器的数量),最后跑一遍最大流,判断满流即可。

#include<bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef pair<int,int> PII;
const int MAXN = 1e4+10;
const double EPS = 1e-12;

int T,n,m,ss,tt,cas;
int p[MAXN],s[MAXN],e[MAXN];
int iter[MAXN],level[MAXN];
struct node{
    int to,cap,rev;
};
vector<node>G[MAXN];

inline void addedge(int from,int to,int cap){
    G[from].push_back(node{to,cap,G[to].size()});
    G[to].push_back(node{from,cap,G[from].size()-1});
}

inline bool bfs(){
    memset(level,0,sizeof(level));
    queue<int>q;
    level[ss]=1;
    q.push(ss);
    while(!q.empty()){
        int x=q.front();q.pop();
        for(int i=0;i<G[x].size();i++){
            node &e=G[x][i];
            if(e.cap>0&&level[e.to]==0){
                level[e.to]=level[x]+1;
                q.push(e.to);
            }
        }
    }
    return level[tt]==0 ? 0 : 1;
}

inline int dfs(int x,int flow){
    if(x==tt)return flow;
    for(int &i=iter[x];i<G[x].size();i++){
        node &e=G[x][i];
        if(e.cap>0&&level[e.to]>level[x]){
            int d=dfs(e.to,min(flow,e.cap));
            if(d>0){
                e.cap-=d;
                G[e.to][e.rev].cap+=d;
                return d;
            }
        }
    }
    return 0;
}

int main()
{
    scanf("%d",&T);
    while(T--){
        scanf("%d %d",&n,&m);
        int sum=0;
        for(int i=0;i<=2000;i++)G[i].clear();
        for(int i=1;i<=n;i++){
            scanf("%d %d %d",&p[i],&s[i],&e[i]);
            sum+=p[i];
        }
        ss=0;tt=2000;
        for(int i=1;i<=n;i++)addedge(0,i,p[i]);
        for(int i=1;i<=n;i++)
            for(int j=s[i];j<=e[i];j++)
                addedge(i,1000+j,1);
        for(int i=1;i<=500;i++)
            addedge(1000+i,2000,m);
        int ans=0;
        while(bfs()){
            memset(iter,0,sizeof(iter));
            int now;
            while((now=dfs(ss,2e9)))
                ans+=now;
        }
        printf("Case %d: ",++cas);
        if(ans==sum)printf("Yes
");
        else printf("No
");
        printf("
");
    }
}


原文地址:https://www.cnblogs.com/Mmasker/p/11917454.html