HDU - 2883 kebab (最大流)

来源:互联网 发布:卓智网络是国企 编辑:程序博客网 时间:2024/05/17 00:51

题目大意:有一个烤肉老板,每个单位时间可以完成M的烤肉
现在有N位客人,给出每位客人来的时间,走的时间,烤肉的数量和每串烤肉所需的单位时间
问这个老板能否完成每位客人的需求

解题思路:这题和HDU 3572相似,但又不能像那题那样做,因为这题时间长度有点大
所以将时间区间当成一个点,将该区间连向超级汇点,容量为区间长度*M
将所有客人连向超级源点,容量为烤肉数量*每串烤肉所需时间
接下来的难点就是怎么将客人和时间区间连起来了
如果时间区间在客人来的时间和走的时间这段区间内,就表明这段时间可以用来帮客人烤肉,所以可以连接,容量为INF
这样图就建好了
附上大神的详细题解
详细题解

#include <cstdio>#include <cstring>#include <algorithm>#include <vector>#include <queue>using namespace std;#define N 1010#define INF 0x3f3f3f3fstruct Edge {    int from, to, cap, flow;    Edge() {}    Edge(int from, int to, int cap, int flow): from(from), to(to), cap(cap), flow(flow) {}};struct ISAP {    int p[N], num[N], cur[N], d[N];    int t, s, n, m;    bool vis[N];    vector<int> G[N];    vector<Edge> edges;    void init(int n) {        this->n = n;        for (int i = 0; i <= n; i++) {            G[i].clear();            d[i] = INF;        }        edges.clear();    }    void AddEdge(int from, int to, int cap) {        edges.push_back(Edge(from, to, cap, 0));        edges.push_back(Edge(to, from, 0, 0));        m = edges.size();        G[from].push_back(m - 2);        G[to].push_back(m - 1);    }    bool BFS() {        memset(vis, 0, sizeof(vis));        queue<int> Q;        d[t] = 0;        vis[t] = 1;        Q.push(t);        while (!Q.empty()) {            int u = Q.front();            Q.pop();            for (int i = 0; i < G[u].size(); i++) {                Edge &e = edges[G[u][i] ^ 1];                if (!vis[e.from] && e.cap > e.flow) {                    vis[e.from] = true;                    d[e.from] = d[u] + 1;                    Q.push(e.from);                }            }        }        return vis[s];    }    int Augment() {        int u = t, flow = INF;        while (u != s) {            Edge &e = edges[p[u]];            flow = min(flow, e.cap - e.flow);            u = edges[p[u]].from;        }        u = t;        while (u != s) {            edges[p[u]].flow += flow;            edges[p[u] ^ 1].flow -= flow;            u = edges[p[u]].from;        }        return flow;    }    int Maxflow(int s, int t) {        this->s = s; this->t = t;        int flow = 0;        BFS();        if (d[s] > n)            return 0;        memset(num, 0, sizeof(num));        memset(cur, 0, sizeof(cur));        for (int i = 0; i < n; i++)            if (d[i] < INF)                num[d[i]]++;        int u = s;        while (d[s] <= n) {            if (u == t) {                flow += Augment();                u = s;            }            bool ok = false;            for (int i = cur[u]; i < G[u].size(); i++) {                Edge &e = edges[G[u][i]];                if (e.cap > e.flow && d[u] == d[e.to] + 1) {                    ok = true;                    p[e.to] = G[u][i];                     cur[u] = i;                    u = e.to;                    break;                }            }            if (!ok) {                int Min = n;                for (int i = 0; i < G[u].size(); i++) {                    Edge &e = edges[G[u][i]];                    if (e.cap > e.flow)                        Min = min(Min, d[e.to]);                }                if (--num[d[u]] == 0)                    break;                num[d[u] = Min + 1]++;                cur[u] = 0;                if (u != s)                    u = edges[p[u]].from;            }        }        return flow;    }};ISAP isap;int S[N], E[N], num[N], T[N], All[N];int n, m;void solve() {    int t, cnt = 0, s = 0, Sum = 0;    for (int i = 1; i <= n; i++) {        scanf("%d%d%d%d", &S[i], &num[i], &E[i], &T[i]);        All[cnt++] = S[i];        All[cnt++] = E[i];        Sum += num[i] * T[i];    }    sort(All, All + cnt);    cnt = unique(All, All + cnt) - All;    t = n + cnt + 1;    isap.init(t);    for (int i = 1; i <= n; i++)        isap.AddEdge(s, i, num[i] * T[i]);    for (int i = 1; i < cnt; i++) {        isap.AddEdge(i + n, t, (All[i] - All[i - 1]) * m);        for (int j = 1; j <= n; j++) {            if (S[j] <= All[i - 1] && E[j] >= All[i]) {                isap.AddEdge(j, i + n, INF);            }        }    }    if (Sum == isap.Maxflow(s, t))        printf("Yes\n");    else        printf("No\n");}int main() {    while (scanf("%d%d", &n, &m) != EOF) {        solve();    }    return 0;}
0 0
原创粉丝点击