zoukankan      html  css  js  c++  java
  • kebab

    传送门
    和我上一篇博客的思路很像,区别在于每一个任务的(s_i,e_i)不一样,这题的(e_i - s_i)很大,所以无法直接全部进行建立
    那么考虑对其进行离散化,也就是或对于区间[l,r]的作为一个结点,然后按照前面的方法去建立
    对于第一层边的建立,容量就是烤肉数 * 单个烤肉的时间
    第二层边的建立,对应的应该是(times[i] - times[i - 1] * m),其中(times)数组是离散化后的时间点,那么容量是时间段 * m
    第三层边的建立,和第二层边一样

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <queue>
    #include <algorithm>
    #define ll long long
    using namespace std;
    const int N = 2000 + 5;
    int n, m, s, t;
    struct Edge{
        int to, next, w;
    }e[N * N];
    int head[N], tot = 1, cur[N]; //弧优化
    void add(int u, int v, int w){
        e[++tot].to = v;
        e[tot].w = w;
        e[tot].next = head[u];
        head[u] = tot;
    }
    int dis[N];
    int dfs(int u, int flow){ //保证了每次DFS都能找到增广路
        if(u == t) return flow;
        int sum = 0;
        for(int i = cur[u]; i && flow > 0; i = e[i].next){
            cur[u] = i;
            int v = e[i].to, w = e[i].w;
            if(w > 0 && dis[v] == dis[u] + 1){
                int t = dfs(v, min(flow, w)); //获取这条增广路的最小流量
                e[i].w -= t; e[i ^ 1].w += t; //减去最小流量,同时反向边加上最小流量
                flow -= t; sum += t;
            }
        }
        if(!sum) dis[u] = 0;//结果u无法到达终点,或者没有增广路,切断经过这个点的路径
        return sum;
    }
    bool bfs(){//分层判断是否有增广路
        memset(dis, 0, sizeof(dis));
        queue<int> q;
        q.push(s); dis[s] = 1; cur[s] = head[s];//弧优化
        while(!q.empty()){
            int u = q.front(); q.pop();
            for(int i = head[u]; i; i = e[i].next){
                int v = e[i].to, w = e[i].w;
                if(w > 0 && !dis[v]) {
                    cur[v] = head[v];// v这个点从head[v]出发是可行的
                    dis[v] = dis[u] + 1;//分层
                    q.push(v);
                    if(v == t) return 1;//已经到达增广路,直接返回
                }
            }
        }
        return dis[t];
    }
    ll Dinic(){
        ll max_flow = 0;
        while(bfs()){
            max_flow += dfs(s, 2e9);
        }
        return max_flow;
    }
    int st[N], ed[N], num[N], ti[N], times[N], k = 0; 
    int main(){
        int n, m;
        while(~scanf("%d%d", &n, &m)){
            memset(head, 0, sizeof(head));
            tot = 1;
            k = 0;
            ll sum = 0;
            for(int i = 1; i <= n; i++){
                scanf("%d%d%d%d", &st[i], &num[i], &ed[i], &ti[i]);
                times[++k] = st[i];
                times[++k] = ed[i];
                sum += num[i] * ti[i];
            }
            sort(times + 1, times + k + 1);
            k = unique(times + 1, times + k + 1) - times;//离散化
            s = 0, t = n + k + 1;
            for(int i = 1; i <= n; i++){//第一层边
                add(s, i, num[i] * ti[i]);
                add(i, s, 0);
            }
    
            for(int i = 1; i <= n; i++){//第二层边
                for(int j = 1; j <= k; j++){
                    if(st[i] <= times[j - 1] && times[j] <= ed[i]){
                        add(i, n + j, 2e9);
                        add(n + j, i, 0);
                    }
                }
            }
            for(int i = 1; i <= k; i++){// 第三层边
                add(n + i, t, (times[i] - times[i - 1]) * m);
                add(t, n + i, 0);
            }
            printf("%s
    ", Dinic() == sum ? "Yes" : "No");
        }
        return 0; 
    }
    
    
  • 相关阅读:
    gThumb 3.1.2 发布,支持 WebP 图像
    航空例行天气预报解析 metaf2xml
    Baruwa 1.1.2 发布,邮件监控系统
    Bisect 1.3 发布,Caml 代码覆盖测试
    MoonScript 0.2.2 发布,基于 Lua 的脚本语言
    Varnish 入门
    快速增量备份程序 DeltaCopy
    恢复模糊的图像 SmartDeblur
    Cairo 1.12.8 发布,向量图形会图库
    iText 5.3.4 发布,Java 的 PDF 开发包
  • 原文地址:https://www.cnblogs.com/Emcikem/p/13260639.html
Copyright © 2011-2022 走看看