zoukankan      html  css  js  c++  java
  • [Bzoj1061][Noi2008]志愿者招募(费用流)

    题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1061

    一开始疯狂想dp,然后队友走过来瞄一眼就告诉我像费用流,菜的真实,jpg。

    一种比较经典的建图方法:

    源点连第一天,流量inf,费用0。

    第n天连汇点,流量inf,费用0。

    第i天连第i+1天,流量inf-a[i](需要的人数),费用0。(限制流量)

    第i种可以选择的人,将Si+1天连Ti天,流量inf,费用Ci。(花钱购买流量)

    菜的真实.jpg

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 const int maxn = 2e6 + 10;
     5 const int inf = 1e7 + 10;
     6 struct node {
     7     int s, e, w, cost, next;
     8 }edge[maxn];
     9 int head[maxn], len;
    10 void init() {
    11     memset(head, -1, sizeof(head));
    12     len = 0;
    13 }
    14 void add(int s, int e, int w, int cost) {
    15     edge[len].s = s;
    16     edge[len].e = e;
    17     edge[len].w = w;
    18     edge[len].cost = cost;
    19     edge[len].next = head[s];
    20     head[s] = len++;
    21 }
    22 void insert(int s, int e, int w, int cost) {
    23     add(s, e, w, cost);
    24     add(e, s, 0, -cost);
    25 }
    26 int  pre[maxn], dis[maxn], vis[maxn];
    27 bool spfa(int s, int e) {
    28     memset(dis, 0x7f, sizeof(dis));
    29     memset(vis, 0, sizeof(vis));
    30     memset(pre, -1, sizeof(pre));
    31     queue<int>q;
    32     q.push(s);
    33     vis[s] = 1, dis[s] = 0;
    34     while (!q.empty()) {
    35         int x = q.front();
    36         q.pop();
    37         vis[x] = 0;
    38         for (int i = head[x]; i != -1; i = edge[i].next) {
    39             int y = edge[i].e;
    40             if (edge[i].w&&dis[y] > dis[x] + edge[i].cost) {
    41                 dis[y] = dis[x] + edge[i].cost;
    42                 pre[y] = i;
    43                 if (vis[y] == 0) {
    44                     vis[y] = 1;
    45                     q.push(y);
    46                 }
    47             }
    48         }
    49     }
    50     return pre[e] != -1;
    51 }
    52 int MCMF(int s, int e) {
    53     int maxans = 0, minans = 0;
    54     while (spfa(s, e)) {
    55         int f = inf;
    56         for (int i = pre[e]; i != -1; i = pre[edge[i].s])
    57             f = min(f, edge[i].w);
    58         maxans += f;
    59         minans += dis[e] * f;
    60         for (int i = pre[e]; i != -1; i = pre[edge[i].s]) {
    61             edge[i].w -= f;
    62             edge[i ^ 1].w += f;
    63         }
    64     }
    65     return minans;
    66 }
    67 int main() {
    68     int n, m;
    69     int x, l, r, cost;
    70     scanf("%d%d", &n, &m);
    71     init();
    72     int w = inf;
    73     for (int i = 1; i <= n; i++) {
    74         scanf("%d", &x);
    75         add(i, i + 1, w - x, 0);
    76         add(i + 1, i, 0, 0);
    77     }
    78     insert(0, 1, w, 0);
    79     insert(n + 1, n + 2, w, 0);
    80     for (int i = 1; i <= m; i++) {
    81         scanf("%d%d%d", &l, &r, &cost);
    82         insert(l, r + 1, w, cost);
    83     }
    84     printf("%d
    ", MCMF(0, n + 2));
    85     return 0;
    86 }
  • 相关阅读:
    linux-nohup后台运行
    linux-友好显示文件大小
    System.exit(0)会跳过finally块的执行
    Spark-scala-API
    Lua协程-测试3
    Lua协程-测试2
    Lua协程
    费马大定理
    Spring事务超时、回滚的相关说明
    springboot测试service层的单元测试
  • 原文地址:https://www.cnblogs.com/sainsist/p/11118402.html
Copyright © 2011-2022 走看看