HDU 2883 kebab【网络流+离散化】

给定n个顾客,第i号顾客在si到达,点了ni个羊肉串,每个羊肉串需要ti个时间烤好。顾客想要在ei得到,一个烤炉只烤m串。问你是否能满足所有顾客的要求?能的话输出“Yes”,否则输出“No”。注意:这ni个羊肉串可以被分开来考,一个单独的羊肉串也能分开烤(比如一个单独的羊肉串需要ti时间,我们把它分成ti份同时烤的话,那么一个羊肉串可以在1个单位时间内拷完)
注意:每个顾客的任务必须在(si,ei]半开半闭的区间内完成.

分析:和这个题很像:HDU3572
这个题时间区间比较大,但是个数并不多,把时间区间给拆出来,离散化一下,然后就是普通的建图了(二层结构);
这个建图真恶心,思路有了,建图一直错。。。就是把整个大的时间区间保存下,就是一个线段一个区间进行离散化。第一层是源点到每一个任务(1~n),权值是ni * ti;第二层是任务到时间区间,权值是:时间区间长度 * 机器数;最后把时间区间连到汇点,权值是时间区间*机器数;

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
typedef long long LL;
using namespace std;

const int MAXN = 1000 + 5;
const int INF = 0x3f3f3f3f;
int head[MAXN], dist[MAXN], vis[MAXN];
int cur[MAXN], si[MAXN], ei[MAXN], a[MAXN << 1];
int top = 0;

struct Edge {
    int to, cap, flow, next;
}edge[MAXN * 10];

void init() {
    top = 0;
    memset(head, -1, sizeof(head));
    memset(vis, 0, sizeof(vis));
}

void addedge(int a, int b, int c) {
    Edge E1 = {b, c, 0, head[a]};
    edge[top] = E1;
    head[a] = top++;
    Edge E2 = {a, 0, 0, head[b]};
    edge[top] = E2;
    head[b] = top++;
}

bool BFS(int st, int ed) {
    memset(dist, -1, sizeof(dist));
    memset(vis, 0, sizeof(vis));
    queue<int> que;
    que.push(st);
    vis[st] = 1;
    dist[st] = 0;
    while(!que.empty()) {
        int u = que.front();
        que.pop();
        for(int i = head[u]; i != -1; i = edge[i].next) {
            Edge E = edge[i];
            if(!vis[E.to] && E.cap > E.flow) {
                dist[E.to] = dist[u] + 1;
                vis[E.to] = 1;
                if(E.to == ed) return true;
                que.push(E.to);
            }
        }
    }
    return false;
}

int DFS(int x, int a, int ed) {
    if(x == ed || a == 0) return a;
    int flow = 0, f;
    for(int& i = cur[x]; i != -1; i = edge[i].next) {
        Edge& E = edge[i];
        if(dist[E.to] == dist[x] + 1 && (f = DFS(E.to, min(a, E.cap - E.flow), ed)) > 0) {
            E.flow += f;
            edge[i^1].flow -= f;
            flow += f;
            a -= f;
            if(a == 0) break;
        }
    }
    return flow;
}

int Maxflow(int st, int ed) {
    int flow = 0;
    while(BFS(st, ed)) {
        memcpy(cur, head, sizeof(head));
        flow += DFS(st, INF, ed);
    }
    return flow;
}

int main()
{
    int n, m;
    while(scanf("%d %d", &n, &m) != EOF) {
        init();
        int ni, ti, sum = 0;
        for(int i = 1; i <= n; ++i) {
            scanf("%d %d %d %d", &si[i], &ni, &ei[i], &ti);
            sum += ni * ti; 
            addedge(0, i, ni * ti);
            a[i] = si[i];
            a[i + n] = ei[i];
        }
        sort(a + 1, a + n + n + 1);
        int ans = n + n;
        for(int i = 2; i <= ans; ++i) {
            addedge(i + n - 1, ans + 2 + n, (a[i] - a[i - 1]) * m);
            for(int j = 1; j <= n; ++j) {
                if(si[j] <= a[i - 1] && a[i] <= ei[j]) {
                    addedge(j, i + n - 1, (a[i] - a[i - 1]) * m);
                }
            }
        }
        if(Maxflow(0, ans + n + 2) < sum) puts("No");
        else puts("Yes");
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_36368339/article/details/80579486