bzoj1061 建图 + 最小费用流
https://www.lydsy.com/JudgeOnline/problem.php?id=106152
对于一个点对上多个点,不太容易建图的时候,考虑逆向思考
申奥成功后,布布经过不懈努力,终于成为奥组委下属公司人力资源部门的主管。布布刚上任就遇到了一个难
题:为即将启动的奥运新项目招募一批短期志愿者。经过估算,这个项目需要N 天才能完成,其中第i 天至少需要
Ai 个人。 布布通过了解得知,一共有M 类志愿者可以招募。其中第i 类可以从第Si 天工作到第Ti 天,招募费用
是每人Ci 元。新官上任三把火,为了出色地完成自己的工作,布布希望用尽量少的费用招募足够的志愿者,但这
并不是他的特长!于是布布找到了你,希望你帮他设计一种最优的招募方案。
Input
第一行包含两个整数N, M,表示完成项目的天数和可以招募的志愿者的种类。 接下来的一行中包含N 个非负
整数,表示每天至少需要的志愿者人数。 接下来的M 行中每行包含三个整数Si, Ti, Ci,含义如上文所述。为了
方便起见,我们可以认为每类志愿者的数量都是无限多的。
Output
仅包含一个整数,表示你所设计的最优方案的总费用。 Sample Input Sample Output Hint
≤ N ≤ , ≤ M ≤ ,题目中其他所涉及的数据均 不超过2^-。
题意
虽然我读完题知道这是一个费用流,但是始终想不到应该怎么建图,在我觉得这题不可能建图的时候看了一下题解。
才知道世界之大无奇不有。
原本正常的建图是以源点连到左边,志愿者连到他对应的天数,但是首先边会很多,并且费用也很难表示,建图的过程显得困难重重。
但是如果换一种方法。
我们将这个点需要多少个志愿者变成这个点还差多少个志愿者到达标准,标准我们设为一个大常数U。看起来好像没有区别,但是事实上我们从源点出U,经过每一天相当于经过了U - a[i]的限制,流量会减少,我们需要用志愿者来使她满流出去,所以对于一个L到R的志愿者,我们建立一条L 到 R + 1,费用为W的边即可,相当于这个志愿者填上了L 到 R的空缺。
真是神奇啊
#include <map>
#include <set>
#include <ctime>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <functional>
using namespace std;
inline int read(){int now=;register char c=getchar();for(;!isdigit(c);c=getchar());
for(;isdigit(c);now=now*+c-'',c=getchar());return now;}
#define For(i, x, y) for(int i=x;i<=y;i++)
#define _For(i, x, y) for(int i=x;i>=y;i--)
#define Mem(f, x) memset(f,x,sizeof(f))
#define Sca(x) scanf("%d", &x)
#define Sca2(x,y) scanf("%d%d",&x,&y)
#define Sca3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define Scl(x) scanf("%lld",&x);
#define Pri(x) printf("%d\n", x)
#define Prl(x) printf("%lld\n",x);
#define CLR(u) for(int i=0;i<=N;i++)u[i].clear();
#define LL long long
#define ULL unsigned long long
#define mp make_pair
#define PII pair<int,int>
#define PIL pair<int,long long>
#define PLL pair<long long,long long>
#define pb push_back
#define fi first
#define se second
typedef vector<int> VI;
const double eps = 1e-;
const int maxn = 1e5 + ;
const int maxm = 2e5 + ;
const int INF = 0x3f3f3f3f;
const int U = 1e5 + ;
const int mod = 1e9 + ;
int N,M,K;
struct MCMF{
struct Edge{
int from,to,cap,flow,nxt;
LL cost;
Edge() {}
Edge(int x,int y,int z,int u,LL v,int n){
from = x; to = y; cap = z; flow = u; cost = v; nxt = n;
}
}edge[maxm];
int E,n,head[maxn];
int inq[maxn],d[maxn],p[maxn],a[maxn];
inline void init(int _n){
n = _n;E = ;
memset(head,-,sizeof(head));
}
inline void addEdge(int f,int t,int c,LL w){
edge[E] = Edge(f,t,c,,w,head[f]);
head[f] = E++;
edge[E] = Edge(t,f,,,-w,head[t]);
head[t] = E++;
}
bool spfa(int s,int t,int &flow,LL &cost){
for(int i = ; i <= n ; i ++) d[i] = INF;
memset(inq,,sizeof(inq));
d[s] = ;inq[s] = ;p[s] = ;a[s] = INF;
queue<int>Q; Q.push(s);
while(!Q.empty()){
int u = Q.front(); Q.pop(); inq[u] = ;
for(int i = head[u]; ~i; i = edge[i].nxt){
Edge &e = edge[i];
if(e.cap <= e.flow || d[e.to] <= d[u] + e.cost) continue;
d[e.to] = d[u] + e.cost;
p[e.to] = i;
a[e.to] = min(a[u],e.cap - e.flow);
if(!inq[e.to]){
Q.push(e.to);
inq[e.to] = ;
}
}
}
if(d[t] == INF) return false;
flow += a[t];
cost += (LL)d[t] * (LL)a[t];
for(int u = t; u != s; u = edge[p[u]].from){
edge[p[u]].flow += a[t];
edge[p[u] ^ ].flow -= a[t];
}
return true;
} int mcmf(int s,int t,LL &cost){
int flow = ;
cost = ;
while(spfa(s,t,flow,cost));
return flow;
}
}g; int main()
{
Sca2(N,M);
int s = ,t = N + ;
g.init(t + ); g.addEdge(s,,U,);
For(i,,N){
LL x; Scl(x);
g.addEdge(i,i + ,U - x,);
}
while(M--){
int l,r; LL c;
Sca2(l,r); Scl(c);
g.addEdge(l,r + ,INF,c);
}
LL cost = ; g.mcmf(s,t,cost);
Prl(cost);
#ifdef VSCode
system("pause");
#endif
return ;
}
bzoj1061 建图 + 最小费用流的更多相关文章
- POJ 2195 一人一房 最小费用流 建图 水题
Going Home Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 21010 Accepted: 10614 Desc ...
- [NOI2008][bzoj1061] 志愿者招募 [费用流+巧妙的建图]
题面 传送门 思路 引入:网络流? 看到这道题,第一想法是用一个dp来完成决策 但是,显然这道题的数据并不允许我们进行dp,尤其是有10000种志愿者的情况下 那么我们就要想别的办法来解决: 贪心?这 ...
- 【BZOJ-1570】BlueMary的旅行 分层建图 + 最大流
1570: [JSOI2008]Blue Mary的旅行 Time Limit: 15 Sec Memory Limit: 162 MBSubmit: 388 Solved: 212[Submit ...
- 【BZOJ-4289】Tax 最短路 + 技巧建图
4289: PA2012 Tax Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 168 Solved: 69[Submit][Status][Dis ...
- CF467D Fedor and Essay 建图DFS
Codeforces Round #267 (Div. 2) CF#267D D - Fedor and Essay D. Fedor and Essay time limit per test ...
- UVa 3487 & 蜜汁建图
题意: 有两家公司都想向政府申请某些资源的使用权,并且他们都提供了一些申请列表,列表中含有申请费用和资源种类,同一家公司的申请列表之间不含有重复的资源.政府只可以完整地接受和拒绝谋一份申请列表,问政府 ...
- POJ 2226 最小点覆盖(经典建图)
Muddy Fields Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 8881 Accepted: 3300 Desc ...
- HDU 5669 线段树优化建图+分层图最短路
用线段树维护建图,即把用线段树把每个区间都标号了,Tree1中子节点有到达父节点的单向边,Tree2中父节点有到达子节点的单向边. 每次将源插入Tree1,汇插入Tree2,中间用临时节点相连.那么T ...
- 【BZOJ-2879】美食节 最小费用最大流 + 动态建图
2879: [Noi2012]美食节 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 1366 Solved: 737[Submit][Status] ...
随机推荐
- Xamarin 简化的Android密钥库签名
安装 开始使用这个新工具不容易.在Visual Studio 2017(即将推出VS 2015),只需转到工具 - >扩展和更新,并搜索“密钥库”来查找扩展名. 下载后,只需重新启动Visual ...
- P2123 皇后游戏
题目背景 还记得 NOIP 2012 提高组 Day1 的国王游戏吗?时光飞逝,光阴荏苒,两年 过去了.国王游戏早已过时,如今已被皇后游戏取代,请你来解决类似于国王游 戏的另一个问题. 题目描述 皇后 ...
- JVM是如何处理异常的
JVM处理异常 异常处理的两大组成要素是抛出异常和捕获异常.这两大要素共同实现程序控制流的非正常转移. 抛出异常可分为显式和隐式两种.显式抛异常的主体是应用程序,指的是在程序中使用throw关键字,手 ...
- js查漏补缺【未完】
1.初始 1.小补. 1.在文本字符串中使用反斜杠对代码行进行换行. document.write("Hello \ World!"); 2.document.write docu ...
- JS获取宽度高度大集合
网页可见区域宽:document.body.clientWidth 网页可见区域高:document.body.clientHeight 网页可见区域宽:document.body.offsetWid ...
- P1064 金明的预算方案
思路:就是一个背包问题 因为数据范围小,所以不把 1个带附着物的东西 拆成 带1个带2个或不带 #include<bits/stdc++.h> using namespace std; ...
- Matplotlib学习---matplotlib的一些基本用法
Matplotlib有两种接口,一种是matlab风格接口,一种是面向对象接口.在这里,统一使用面向对象接口.因为面向对象接口可以适应更复杂的场景,在多图之间进行切换将变得非常容易. 首先导入matp ...
- 【JSOI2008】火星人prefix 哈希 非旋转treap
题目大意 就是给你一个字符串,有三种操作,共\(m\)个 \(Q~x~y\):询问第\(x\)个后缀和第\(y\)个后缀的LCP \(R~x~y\):把第\(x\)个字符改成\(y\) \(I~x~y ...
- NOIP2015斗地主(搜索+模拟+贪心)
%%%Luan 题面就不说了,和斗地主一样,给一组牌,求最少打几次. 注意一点,数据随机,这样我们瞎搞一搞就可以过,虽然直接贪心可以证明是错的. 枚举方法,每次搜索按照(三顺子>二顺子>普 ...
- This license xxx has been cancelled 解决
上节回顾:JetBrains全家桶破解思路 hosts屏蔽一下即可,Linux是:/etc/hosts 0.0.0.0 account.jetbrains.com 重新输入Code即可,最后补一个地址 ...