zoukankan      html  css  js  c++  java
  • 【HDU 4807】Lunch Time 最小费用最大流

    题意

    在一个有向图当中,现在每一条边带有一个容量,现在有K个人在起点,需要到终点去吃饭,询问这K个人最后一个人到达食堂的最小时间是多少


    贴一篇题解:http://blog.csdn.net/u013761036/article/details/38268335

    代码

    #include <bits/stdc++.h>
    #define MAXN 5005
    #define MAXM 100010
    #define inf 0x7f7f7f7f
    using namespace std;
    struct Edge{
        int to, nxt, cap, cost;
    }edge[MAXM];
    int head[MAXN], cnt;
    int dis[MAXN], last[MAXN], vis[MAXN];
    int flow, cost, ans;
    void init() {
        memset(head, -1, sizeof(head));
        cnt = 0;
    }
    void add_edge(int u, int v, int cap, int cost) {
        edge[cnt].to = v;
        edge[cnt].cap = cap;
        edge[cnt].cost = cost;
        edge[cnt].nxt = head[u];
        head[u] = cnt++;
    }
    bool spfa(int s, int t) {
        memset(last, -1, sizeof(last));
        memset(dis, 127, sizeof(dis));
        memset(vis, 0,sizeof(vis));
        dis[s] = 0; vis[s] = 1; last[s] = -1;
        queue<int> que; que.push(s);
        while(!que.empty()) {
            int u = que.front(); que.pop();
            vis[u] = 0;
            for(int i = head[u]; ~i; i = edge[i].nxt) {
                int v = edge[i].to;
                if(edge[i].cap && dis[v] > dis[u] + edge[i].cost) {
                    dis[v] = dis[u] + edge[i].cost;
                    last[v] = i;
                    if(!vis[v]) {
                        que.push(v);
                        vis[v] = 1;
                    }
                }
            }
        }
        return last[t] != -1;
    }
    void mcmf(int s, int t, int k) {
        flow = 0, cost = 0; ans = inf;
        int last_time, tot = k;
        while(spfa(s, t)) {
            int Min = inf;
            for(int i = last[t]; ~i; i = last[edge[i ^ 1].to]) Min = min(Min, edge[i].cap);
            for(int i = last[t]; ~i; i = last[edge[i ^ 1].to]) {
                cost += edge[i].cost * Min;
                edge[i].cap -= Min; edge[i ^ 1].cap += Min;
            }
            tot -= flow * (dis[t] - last_time) + Min; 
            flow += Min; last_time = dis[t]; tot = max(tot, 0);
            ans = min(ans, dis[t] + (int)ceil(1.0 * tot / flow));
            if(tot < 1) break;
        }
    }
    int n, m, k, a, b, c;
    int main() {
        while(scanf("%d%d%d", &n, &m, &k) != EOF) {
            init();
            for(int i = 1; i <= m; ++i) {
                scanf("%d%d%d", &a, &b, &c); a++; b++;
                add_edge(a, b, c, 1); add_edge(b, a, 0, -1);
            }
            if(k == 0) {printf("0
    "); continue;}
            mcmf(1, n, k);
            if(ans == inf) printf("No solution
    "); else printf("%d
    ", ans);
        }
        return 0;
    }
    
  • 相关阅读:
    LeetCode 75. Sort Colors(按颜色进行排序)
    LeetCode 451. Sort Characters By Frequency(按照字符出现次数对字符串排序)
    LeetCode 347. Top K Frequent Elements(出现频率最多的 k 个元素)
    LeetCode 215. Kth Largest Element in an Array(数组求第k大)
    CF #629 Div.3 E(LCA)F
    系统函数
    CASE表达式
    循环得出数据库中所有的 DB_ID,DB_NAME
    数据库的编码问题
    检验临时表是否存在
  • 原文地址:https://www.cnblogs.com/ogiso-setsuna/p/8400618.html
Copyright © 2011-2022 走看看