hdu3572 建图 最大流

来源:互联网 发布:全能视频转换器软件 编辑:程序博客网 时间:2024/05/22 15:06

题意:
给N个任务,M台机器。每个任务有最早才能开始做的时间S,deadline E,和持续工作的时间P。每个任务可以分段进行,但是在同一时刻,一台机器最多只能执行一个任务. 问存不存在可行的工作时间。

题解:
因为总天数<=500,每个任务可以分段进行,我们可以把每一天看做一个节点,然后把每个任务也看成一个节点,最后引入源点和终点。
建图:
①源点和每个任务之间边的权值为 P
②任务和相应的天数之间(S-E)之间边的权值为 1
③天数和终点之间边的权值为 M
最后判断最大流是否等于任务需要的天数和

#include <bits/stdc++.h>using namespace std;const int INF  = 0x3f3f3f3f;const int maxn = 1008;const int Mod  = 1e9 + 7;#define ll       long long#define mem(x,y) memset(x,y,sizeof(x))#define IO       ios_base::sync_with_stdio(0), cin.tie(0);inline ll gcd(ll a, ll b) {return a % b == 0 ? b : gcd(b, a % b);}inline ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}inline ll quick_pow(ll x, int k) {ll ans = 1; while (k) { if (k & 1) ans = (ans * x) % Mod; x = x * x % Mod;  k >>= 1; } return ans;}int mp[maxn][maxn], dep[maxn], m, n;struct Node {    int  v, w, re_id;    Node() {};    Node(int a, int b, int c) {        v = a, w = b, re_id = c;    }};vector<Node> node[maxn];void addEdge(int u, int v, int w) {    node[u].push_back(Node(v, w, node[v].size()));    node[v].push_back(Node(u, 0, node[u].size() - 1));}int bfs(int s, int t) {    queue<int> Q;    mem(dep, -1);    dep[s] = 0;    Q.push(s);    while (!Q.empty()) {        int u = Q.front();        Q.pop();        for (int i = 0; i < node[u].size(); i++) {            int v = node[u][i].v;            if (node[u][i].w > 0 && dep[v] == -1) {                dep[v] = dep[u] + 1;                Q.push(v);            }        }    }    return dep[t] != -1;}int  dfs(int s, int t, int f) {    if (s == t || f == 0) return f;    int sumf = 0;    for (int i = 0; i < node[s].size(); i++) {        int v = node[s][i].v;        if (node[s][i].w > 0 && dep[v] == dep[s] + 1) {            int tmp = dfs(v, t, min(f, node[s][i].w));            if (tmp > 0) {                node[s][i].w -= tmp;                node[v][node[s][i].re_id].w += tmp;                sumf += tmp, f -= tmp;                //  return tmp;            }        }    }    if (sumf == 0) dep[s] = -1;    return sumf;}int dinic(int s, int t) {    int ans = 0;    while (bfs(s, t))  ans += dfs(s, t, INF);  //  cout << ans << endl;    return ans;}int main() {    int t, icase = 1, a, b, N, M, c, sum;    cin >> t;    while (t--) {        for (int i = 0; i < maxn; i++)node[i].clear();        sum = 0;        cin >> N >> M;        n = 500 + N + 1;        for (int i = 1; i <= N; i++) {            scanf("%d%d%d", &a, &b, &c);            sum += a;            addEdge(0, i, a);            for (int j = b; j <= c; j++) addEdge(i, j + N, 1);        }        for (int i = 1; i <= 500; i++) addEdge(i + N, n, M);        printf("Case %d: %s\n\n", icase++, dinic(0, n) == sum ? "Yes" : "No");    }}