最大流任务调度+离散化——hdu2883

 思想就是把时间段离散化,然后用个点来表示一段时间

#include<iostream>
#include<cstdio>
#include<cstring>
#include <algorithm>
#include <math.h>
#include <queue>
using namespace std;
const int N = 1005;
const int INF = 999999999;
struct Edge{
    int v,w,next;
}edge[N*N];
int head[N];
int level[N];
int tot;
void init()
{
    memset(head,-1,sizeof(head));
    tot=0;
}
void addEdge(int u,int v,int w,int &k)
{
    edge[k].v = v,edge[k].w=w,edge[k].next=head[u],head[u]=k++;
    edge[k].v = u,edge[k].w=0,edge[k].next=head[v],head[v]=k++;
}
int BFS(int src,int des)
{
    queue<int>q;
    memset(level,0,sizeof(level));
    level[src]=1;
    q.push(src);
    while(!q.empty())
    {
        int u = q.front();
        q.pop();
        if(u==des) return 1;
        for(int k = head[u]; k!=-1; k=edge[k].next)
        {
            int v = edge[k].v;
            int w = edge[k].w;
            if(level[v]==0&&w!=0)
            {
                level[v]=level[u]+1;
                q.push(v);
            }
        }
    }
    return -1;
}
int dfs(int u,int des,int increaseRoad){
    if(u==des||increaseRoad==0) return increaseRoad;
    int ret=0;
    for(int k=head[u];k!=-1;k=edge[k].next){
        int v = edge[k].v,w=edge[k].w;
        if(level[v]==level[u]+1&&w!=0){
            int MIN = min(increaseRoad-ret,w);
            w = dfs(v,des,MIN);
            if(w > 0)
            {
                edge[k].w -=w;
                edge[k^1].w+=w;
                ret+=w;
                if(ret==increaseRoad) return ret;
            }
            else level[v] = -1;
            if(increaseRoad==0) break;
        }
    }
    if(ret==0) level[u]=-1;
    return ret;
}
int Dinic(int src,int des)
{
    int ans = 0;
    while(BFS(src,des)!=-1) ans+=dfs(src,des,INF);
    return ans;
}
int n,m;
int s[N],num[N],e[N],t[N];
int time[N];
int main()
{
    while(scanf("%d%d",&n,&m)!=EOF){
        init();
        int k = 0;
        int sum = 0;
        for(int i=1;i<=n;i++){
            scanf("%d%d%d%d",&s[i],&num[i],&e[i],&t[i]);
            sum += num[i]*t[i];
            time[++k] = s[i];
            time[++k] = e[i];
        }
        sort(time+1,time+k+1);
        int cnt = 1;
        for(int i=2;i<=k;i++){
            if(time[i]==time[i-1]) continue;
            time[++cnt] = time[i];
        }
        int src = 0,des = n+cnt+1;
        for(int i=1;i<=n;i++){
            addEdge(src,i,num[i]*t[i],tot);
        }
        for(int i=1;i<=n;i++){
            for(int j=1;j<=cnt;j++){
                if(s[i]<=time[j-1]&&time[j]<=e[i]){
                    addEdge(i,n+j,INF,tot);
                }
            }
        }
        for(int i=1;i<=cnt;i++){
            addEdge(n+i,des,(time[i]-time[i-1])*m,tot);
        }
        if(Dinic(src,des)==sum) printf("Yes\n");
        else printf("No\n");
    }
    return 0;
}

 

posted on 2019-06-09 10:32  zsben  阅读(295)  评论(0编辑  收藏  举报

导航