hdu 2883 网络流+离散化

 链接:http://acm.hdu.edu.cn/showproblem.php?pid=2883


题意: 有一个烤肉店,有n个客人,每个客人点ni个ti时间花费的烤肉,每分钟最多烤M个。客人有到和离开的时间限制,问是否可以满足所有客人的需求。

(和 hdu3572很像,但是有两点不同。1.3572中每个物品只能有一个机器做,所以网络中物品到单位时间的容量是1.但是这个题不一样,只要能流流不满流多少都没关 系。2.这里时间区间很长,要考虑离散化)


思路:源点 -》客人(容量花费时间)-》离散化后的时间(容量无穷)-》汇点(每个时间的容量上限)

所以跑一遍网络流如果是满流就说明可以啦,经典的模型,SAP玩家莽了过去。。。


代码:

#include <stdio.h>
#include <algorithm>
#include <iostream>
#include <string.h>
using namespace std;

const int MAXN=1100;
int maze[MAXN][MAXN];
int gap[MAXN],dis[MAXN],pre[MAXN],cur[MAXN];
int sap(int start,int end,int nodenum){
    memset(cur,0,sizeof(cur));
    memset(dis,0,sizeof(dis));
    memset(gap,0,sizeof(gap));
    int u=pre[start]=start,maxflow=0,aug=-1;
    gap[0]=nodenum;
    while(dis[start]<nodenum){
        loop:
        for(int v=cur[u]; v<nodenum; v++)
            if(maze[u][v] && dis[u]==dis[v]+1){
                if(aug==-1 || aug>maze[u][v])aug=maze[u][v];
                pre[v]=u;
                u=cur[u]=v;
                if(v==end){
                    maxflow+=aug;
                    for(u=pre[u]; v!=start; v=u,u=pre[u]){
                        maze[u][v]-=aug;
                        maze[v][u]+=aug;
                    }
                    aug=-1;
                }
                goto loop;
            }
        int mindis=nodenum-1;
        for(int v=0; v<nodenum; v++)
            if(maze[u][v]&&mindis>dis[v]){
                cur[u]=v;
                mindis=dis[v];
            }
        if((--gap[dis[u]])==0)break;
        gap[dis[u]=mindis+1]++;
        u=pre[u];
    }
    return maxflow;
}

int n,m,a,b,c,d,tm[MAXN][2],s[MAXN];

int main(){
    int t,cas=1;
    while(scanf("%d%d",&n,&m)!=EOF){
        memset(maze,0,sizeof(maze));
        int sum=0,cnt=0;
        for(int i=0;i<n;i++){
            scanf("%d%d%d%d",&tm[i][0],&b,&tm[i][1],&d);
            maze[0][i+1]=b*d;
            s[cnt++]=tm[i][0];
            s[cnt++]=tm[i][1];
            sum+=b*d;
        }
        sort(s,s+cnt);
        cnt=(int)(unique(s,s+cnt)-s);
        for(int i=0;i<n;i++){
            for(int j=1;j<cnt;j++)
                if(tm[i][0]<=s[j-1]&&tm[i][1]>=s[j])
                    maze[i+1][j+n]=1e6;
        }
        for(int j=1;j<cnt;j++) maze[j+n][cnt+n+1]=m*(s[j]-s[j-1]);
        if(sum==sap(0,cnt+n+1,cnt+n+2))  printf("Yes\n");
        else printf("No\n");
    }
}


posted @ 2016-10-27 16:17  zhangxianlong  阅读(113)  评论(0编辑  收藏  举报