zoukankan      html  css  js  c++  java
  • bzoj2245

    费用流

    比较裸的费用流,唯一的问题在于费用,由于费用是单调递增的,那么我们可以拆边,源点连向每个人source->i,f=ti-ti-1,c=w,这样就好了,因为费用递增,所以符合费用流的贪心思想,肯定先选小的费用,再走大的费用

    #include<bits/stdc++.h>
    using namespace std;
    const int N = 610, inf = 0x3f3f3f3f;
    struct edge {
        int nxt, to, f;
        long long c;
    } e[N * N << 2];
    int n, m, k, source, sink, tot, cnt = 1, sum;
    int a[N][N], head[N], pree[N], prev[N], t[N], vis[N], w[N], day[N], c[N], l[N], p[N];
    long long d[N];
    inline void link(int u, int v, int f, long long c)
    {
        e[++cnt].nxt = head[u];
        head[u] = cnt;
        e[cnt].f = f;
        e[cnt].to = v;
        e[cnt].c = c;
    }
    inline void insert(int u, int v, int f, int c)
    {
        link(u, v, f, c);
        link(v, u, 0, -c);
    }
    bool spfa()
    {
        memset(d, -1, sizeof(d));
        d[source] = 0;
        queue<int> q;
        q.push(source);
        while(!q.empty())
        {
            int u = q.front();
            q.pop();
            vis[u] = 0;
            for(int i = head[u]; i; i = e[i].nxt) if(e[i].f && (d[e[i].to] > d[u] + e[i].c || d[e[i].to] == -1))
            {
                pree[e[i].to] = i;
                prev[e[i].to] = u;
                d[e[i].to] = d[u] + e[i].c;
                if(vis[e[i].to] == 0)
                {
                    q.push(e[i].to);
                    vis[e[i].to] = 1;
                }
            }
        }
        return d[sink] != -1; 
    }
    inline long long Edmonds_Karp()
    {
        long long ans = 0;
        while(spfa())
        {
            int now = sink, delta = inf;
            while(now != source)
            {
                delta = min(delta, e[pree[now]].f);
                now = prev[now];
            }
            now = sink;
            while(now != source)
            {
                e[pree[now]].f -= delta;
                e[pree[now] ^ 1].f += delta; 
                now = prev[now];
            }
            ans += (long long)delta * d[sink];
        } 
        return ans;
    }
    int main()
    {
        cin >> m >> n;
        source = 0;
        sink = m + n + 1;
        for(int i = 1; i <= n; ++i) 
        {
            int c;
            scanf("%d", &c);
            insert(i + m, sink, c, 0);
        }    
        for(int i = 1; i <= m; ++i)
            for(int j = 1; j <= n; ++j) 
            {
                int x;
                scanf("%d", &x);
                if(x == 1) insert(i, j + m, inf, 0);
            }
        for(int i = 1; i <= m; ++i)
        {
            int s;
            scanf("%d", &s);
            for(int j = 1; j <= s; ++j) scanf("%d", &t[j]);
            t[++s] = inf;
            for(int j = 1; j <= s; ++j)
            {
                long long w;
                scanf("%lld", &w);
                insert(source, i, t[j] - t[j - 1], w);
            }
        }    
        cout << Edmonds_Karp();
        return 0;
    }
    View Code
  • 相关阅读:
    不同压测场景的区别
    常用的re模块的正则匹配的表达式
    了解爬虫
    robots.txt 协议
    vue前台配置
    短信验证码的使用
    创建表
    数据库配置
    后台:Django项目创建
    虚拟环境的搭建
  • 原文地址:https://www.cnblogs.com/19992147orz/p/7507496.html
Copyright © 2011-2022 走看看