bzoj1061: [Noi2008]志愿者招募

orz

题解戳这里 https://www.byvoid.com/blog/noi-2008-employee/

暂时只能理解下

由于不等式不能作差,加上Yi变成等式作差

作差后每个X最多出现一次,这样就可以考虑两个之间的影响了(通过连边,这里流出去这么多那里就要流进来这么对,对应一正一负)

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<cstdlib>
  4 #include<algorithm>
  5 #include<iostream>
  6
  7 using namespace std;
  8
  9 void setIO(const string& s) {
 10     freopen((s + ".in").c_str(), "r", stdin);
 11     freopen((s + ".out").c_str(), "w", stdout);
 12 }
 13 template<typename Q> Q read(Q& x) {
 14     static char c, f;
 15     for(f = 0; c = getchar(), !isdigit(c); ) if(c == ‘-‘) f = 1;
 16     for(x = 0; isdigit(c); c = getchar()) x = x * 10 + c - ‘0‘;
 17     if(f) x = -x;
 18     return x;
 19 }
 20 template<typename Q> Q read() {
 21     static Q x; read(x); return x;
 22 }
 23 // MCMF
 24
 25 const int N = 1000 + 10, M = 25000 + 10, INF = ~0u >> 1;
 26
 27 struct Edge {
 28     int to, adv, cost;
 29     Edge *next;
 30     Edge(int to = 0, int adv = 0, int cost = 0, Edge *next = 0) : to(to), adv(adv), cost(cost), next(next) {}
 31 }pool[M * 2], *pis = pool, *fir[N];
 32
 33 void AddEdge(int u, int v, int w, int c) {
 34     fir[u] = new(pis++) Edge(v, w, c, fir[u]);
 35     fir[v] = new(pis++) Edge(u, 0, -c, fir[v]);
 36 }
 37
 38 #define inv(p) (pool + ( ((p) - pool)^1 ))
 39
 40 namespace MCMF {
 41     int n, s, t;
 42     int d[N], q[N], ql, qr, a[N];
 43     Edge *pre[N];
 44     bool inq[N];
 45
 46     bool insert(int u, int dis, int aug) {
 47         if(d[u] > dis) {
 48             a[u] = aug;
 49             d[u] = dis;
 50             if(!inq[u]) {
 51                 q[qr++] = u;
 52                 if(qr == N) qr = 0;
 53                 inq[u] = 1;
 54             }
 55             return 1;
 56         }return 0;
 57     }
 58
 59     bool SPFA(int& flow, int& cost) {
 60         for(int u = 1; u <= n; u++) d[u] = INF, inq[u] = 0;
 61         insert(s, 0, INF);
 62         while(ql ^ qr) {
 63             int u = q[ql++]; if(ql == N) ql = 0; inq[u] = 0;
 64             for(Edge *p = fir[u]; p; p = p->next) if(p->adv) {
 65                 if(insert(p->to, d[u] + p->cost, min(a[u], p->adv))) {
 66                     pre[p->to] = p;
 67                 }
 68             }
 69         }
 70         if(d[t] == INF) return 0;
 71         flow += a[t];
 72         cost += d[t] * a[t];
 73         for(int u = t; u != s; u = inv(pre[u])->to) {
 74             pre[u]->adv -= a[t];
 75             inv(pre[u])->adv += a[t];
 76         }
 77         return 1;
 78     }
 79
 80     int main(int _n ,int _s, int _t) {
 81         n = _n, s = _s, t = _t;
 82         int flow = 0, cost = 0;
 83         while(SPFA(flow, cost));
 84         return cost;
 85     }
 86 }
 87
 88 const int maxn = 1000 + 10, maxm = 10000 + 10;
 89 int demand[maxn];
 90
 91 int main() {
 92 #ifdef DEBUG
 93     freopen("in.txt", "r", stdin);
 94     freopen("out.txt", "w", stdout);
 95 #endif
 96
 97     int n = read<int>(), m = read<int>();
 98     int s = n + 2, t = s + 1;
 99     for(int i = 1; i <= n; i++) {
100         read(demand[i]);
101         AddEdge(i + 1, i, INF, 0);
102     }
103     for(int i = 1; i <= n + 1; i++) {
104         int dlt = demand[i] - demand[i - 1];
105         if(dlt >= 0) AddEdge(s, i, dlt, 0);
106         else AddEdge(i, t, -dlt, 0);
107     }
108     int l, r, c;
109     for(int i = 1; i <= m; i++) {
110         read(l), read(r), read(c);
111         AddEdge(l, r + 1, INF, c);
112     }
113
114     printf("%d\n", MCMF::main(t, s, t));
115
116     return 0;
117 }

时间: 2024-10-18 01:30:07

bzoj1061: [Noi2008]志愿者招募的相关文章

[BZOJ1061] [Noi2008] 志愿者招募 (费用流)

Description 申奥成功后,布布经过不懈努力,终于成为奥组委下属公司人力资源部门的主管.布布刚上任就遇到了一个难 题:为即将启动的奥运新项目招募一批短期志愿者.经过估算,这个项目需要N 天才能完成,其中第i 天至少需要 Ai 个人. 布布通过了解得知,一共有M 类志愿者可以招募.其中第i 类可以从第Si 天工作到第Ti 天,招募费用 是每人Ci 元.新官上任三把火,为了出色地完成自己的工作,布布希望用尽量少的费用招募足够的志愿者,但这 并不是他的特长!于是布布找到了你,希望你帮他设计一种

【费用流】BZOJ1061[NOI2008]-志愿者招募

[题目大意] 一个项目需要n天完成,其中第i天至少需要Ai个人.共有m类人可以招募,其中第i类可以从第Si天做到第Ti天,每人的招募费用为Ci元.求最小招募费用. [思路] byvoid神犇的建图详解,对理解网络流有很好的帮助,下面再引用一下,原po请戳:★ 这道题正确的解法是构造网络,求网络最小费用最大流,但是模型隐藏得较深,不易想到.构造网络是该题的关键,以下面一个例子说明构图的方法和解释. 例如一共需要4天,四天需要的人数依次是4,2,5,3.有5类志愿者,如下表所示: 种类 1 2 3

BZOJ1061 NOI2008 志愿者招募 单纯形

题意:给定M个志愿者和工作时间的长度N,每个志愿者由工作时间[l,r]和费用c来描述,每个单位时间需要t名志愿者,保证有解,求最少总花费. 题解: (公式太多就用图片代替了QAQ) 这个题标算貌似是费用流啊,不太清楚……总而言之设x[i]为i这个人要不要,b[i]为各个时间所需的志愿者数量,a[i][j]为i时间j这名志愿者能不能起作用,c[i]为i的费用,然后就是裸的线性规划 #include <cmath> #include <cstdio> #include <cstr

线性规划费用流解法(Bzoj1061: [Noi2008]志愿者招募)

题面 传送门 Sol 线性规划费用流解法用与求解未知数为非负数的问题 这道题可以列出一堆形如 \(x[i]+x[j]+x[k]+...>=a[p]\) 的不等式 我们强行给每个式子减去一个东西,使他变成这样 \(x[i]+x[j]+x[k]+...-y[p]==a[p]\) 然后相邻两个式子差分一下 把每个式子看成一个点 那么这样后,在这个题中所有的未知数只会出现在一个方程中 等式左边符号是正的向符号为负的方程连边,费用为代价,如果是补的未知数\(y\),那么费用为零 右边的数是正的连\(s\)

bzoj1061: [Noi2008]志愿者招募

线性规划与费用流.http://www.cnblogs.com/iiyiyi/p/5616080.html.数组范围开错了!!!然后2.31-1=0x7fffffff!=0x7f7f7f7f. 开始以为是+Y[i]然后add(i,i+1,inf,0)一直调一直调... #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<queue>

[Noi2008]志愿者招募

1061: [Noi2008]志愿者招募 Time Limit: 20 Sec  Memory Limit: 162 MB Submit: 5017  Solved: 2989 [Submit][Status][Discuss] Description 申奥成功后,布布经过不懈努力,终于成为奥组委下属公司人力资源部门的主管.布布刚上任就遇到了一个难 题:为即将启动的奥运新项目招募一批短期志愿者.经过估算,这个项目需要N 天才能完成,其中第i 天至少需要 Ai 个人. 布布通过了解得知,一共有M

BZOJ 1061 [Noi2008]志愿者招募

1061: [Noi2008]志愿者招募 Time Limit: 20 Sec  Memory Limit: 162 MBSubmit: 2547  Solved: 1600[Submit][Status][Discuss] Description 申奥成功后,布布经过不懈努力,终于成为奥组委下属公司人力资源部门的主管.布布刚上任就遇到了一个难题:为即将启动的奥运新项目招募一批短期志愿者.经过估算,这个项目需要N 天才能完成,其中第i 天至少需要Ai 个人. 布布通过了解得知,一共有M 类志愿者

BZOJ 1061: [Noi2008]志愿者招募 [单纯形法]

1061: [Noi2008]志愿者招募 Time Limit: 20 Sec  Memory Limit: 162 MBSubmit: 3975  Solved: 2421[Submit][Status][Discuss] Description 申奥成功后,布布经过不懈努力,终于成为奥组委下属公司人力资源部门的主管.布布刚上任就遇到了一个难 题:为即将启动的奥运新项目招募一批短期志愿者.经过估算,这个项目需要N 天才能完成,其中第i 天至少需要 Ai 个人. 布布通过了解得知,一共有M 类志

【BZOJ 1061】 [Noi2008]志愿者招募

1061: [Noi2008]志愿者招募 Time Limit: 20 Sec  Memory Limit: 162 MB Submit: 2066  Solved: 1282 [Submit][Status] Description 申奥成功后,布布经过不懈努力,终于成为奥组委下属公司人力资源部门的主管.布布刚上任就遇到了一个难题:为即将启动的奥运新项目招募一批短期志愿者.经过估算,这个项目需要N 天才能完成,其中第i 天至少需要Ai 个人. 布布通过了解得知,一共有M 类志愿者可以招募.其中