HDU2883 kebab(最大流)

来源:互联网 发布:ipsos待遇 知乎 编辑:程序博客网 时间:2024/05/22 04:35

n位顾客要找老板烤肉串,第i个人要烤Ni串,每串烤Ti分钟,可以分成几个部分来烤,但是必须在Si之后才能开始烤,而且必须在Ei之前烤完(个人认为题目描述不清,应该是时间区间 (Si,Ei] )。烤炉每分钟可以同时烤m单位的肉串(也就是说,每个人要烤肉的总量是NiTi单位)。问是否能够满足所有顾客的需求。
1N200,1M1000,1Ni,Ti50,1Si<Ei1,000,000
这道题类似于HDU3572 Task Schedule,只是建图的方式不同。
传送门:http://acm.hdu.edu.cn/showproblem.php?pid=3572
题解:http://blog.csdn.net/cqbzwja/article/details/50877048
这道题不能像上面那道题一样把时间分成1分钟的小段,因为106太大。我们需要按照所有人的起始和终止时间排序把时间分段,一个段的时间算一个节点,这样最多只会有400个时间点。
源点s向每个人连边,容量为NiSi表示需要烤的总单位;每个人向对应的时间区间连边,即所有的时间段j满足[Sj,Ei][Si,Ei],至于时间段j是什么,看我的代码就懂了;每个时间段向汇点连容量为(EjSj)M的边,表示这段时间中烤肉的最大单位数。
最后求出最大流。比较ni=1NiSimaxflow的大小。

#include<cstdio>#include<cstring>#include<vector>#include<algorithm>#define MAXN 100010#define INF 0x3f3f3f3fusing namespace std;inline int Min(int a,int b){return a<b?a:b;}struct E{    int v,w,op;    E(){}    E(int a,int b,int c)    {v = a; w = b; op = c;}};vector<E> g[MAXN];int d[MAXN],vd[MAXN],s,t,ni[MAXN],ti[MAXN],si[MAXN],ei[MAXN];int N,M,cnt,table[MAXN],flow,sum;int aug(int i,int augco){    int augc = augco,j,mind = t-1,delta,sz = g[i].size();    if(i == t) return augco;    for(j = 0; j < sz; j++)    {        int v = g[i][j].v;        if(g[i][j].w)        {            if(d[i] == d[v]+1)            {                delta = Min(augc,g[i][j].w);                delta = aug(v,delta);                g[i][j].w -= delta;                g[v][g[i][j].op].w += delta;                augc -= delta;                if(d[s] >= t) return augco - augc;                if(augc == 0) break;            }            if(d[v] < mind) mind = d[v];        }    }    if(augc == augco)    {        vd[d[i]]--;        if(vd[d[i]] == 0) d[s] = t;        d[i] = mind+1;        vd[d[i]]++;    }    return augco-augc;}void sap(){    memset(d,0,sizeof d);    memset(vd,0,sizeof vd);    flow = 0;    vd[0] = t;    while(d[s] < t)        flow += aug(s,INF);}void init(){    for(int i = 1; i <= N; i++)        ni[i] = ti[i] = si[i] = ei[i] = 0;    for(int i = 1; i <= t; i++)        g[i].clear();    memset(table,0,sizeof table);    cnt = sum = 0;}int main(){    while(scanf("%d%d",&N,&M) != EOF)    {        s = N+1;        for(int i = 1; i <= N; i++)        {            scanf("%d%d%d%d",&si[i],&ni[i],&ei[i],&ti[i]);            table[++cnt] = si[i];            table[++cnt] = ei[i];            sum += ni[i]*ti[i];            g[s].push_back(E(i,ni[i]*ti[i],g[i].size()));            g[i].push_back(E(s,0,g[s].size()-1));        }        sort(table+1,table+cnt+1);        int len = unique(table+1,table+cnt+1) - (table+1);        t = s+len+1;        for(int i = 1; i <= N; i++)            for(int j = 2; j <= len; j++)                if(si[i] <= table[j-1]&&ei[i] >= table[j])                {                    int x = s+j-1;                    g[i].push_back(E(x,INF,g[x].size()));                    g[x].push_back(E(i,0,g[i].size()-1));                }        for(int i = 2; i <= len; i++)        {            int x = s+i-1;            g[x].push_back(E(t,(table[i]-table[i-1])*M,g[t].size()));            g[t].push_back(E(x,0,g[x].size()-1));        }        sap();        if(flow == sum) printf("Yes\n");        else printf("No\n");        init();    }}
0 0