Codeforces 730I [费用流]
/*
不要低头,不要放弃,不要气馁,不要慌张
题意:
给两行n个数,要求从第一行选取a个数,第二行选取b个数使得这些数加起来和最大。
限制条件是第一行选取了某个数的条件下,第二行不能选取对应位置的数。 思路:
比赛的时候一直在想如何dp。没有往网络流的方向多想想。赛后看到tag想了想,咦,费用流可做。
所以思路是最小费用最大流,dp如今都不知如何做。
将一个位置拆分成3个点,从超级源点分别到1号点连容量为a,价值为0 的边,往2号点连容量为b,价值为0的边。
对于每个位置,从1号点和2号点分别向每个位置拆分出的第一个点连一条容量为1,价值为0的边。然后从该点分别向其它两个点连容量为1,价值为
给定的点,然后这两个点均向超级汇点连接一条容量为1价值为0的边。
跑一下最小费用最大流。 */
#include<stdio.h>
#include<queue>
#define MAXN 55000
#define MAXM 20002*5
#define INF 0x3f3f3f3f
using namespace std;
int a[MAXN],b[MAXN];
int n;
//起点编号必须最小,终点编号必须最大
bool vis[MAXN]; //spfa中记录是否在队列里边
struct edge{
edge *next,*op; //op是指向反向边
int t,c,v; //t下一个点编号,c容量,v权值
}ES[MAXM],*V[MAXN]; //ES边静态邻接表,V点的编号
int N,M,S,T,EC=-; //S源点最小,T汇点最大,EC当前边数
int demond[MAXN],sp[MAXN],prev[MAXN]; //spSPFA中记录距离,prev记录上一个点路径
edge *path[MAXN]; //与prev同步记录,记录到上一条边
void addedge(int a,int b,int v,int c=INF){
edge e1={V[a],,b,c,v},e2={V[b],,a,,-v};
ES[++EC]=e1;V[a]=&ES[EC];
ES[++EC]=e2;V[b]=&ES[EC];
V[a]->op=V[b];V[b]->op=V[a];
}
void init(){
int num1,num2;
scanf("%d%d%d",&n,&num1,&num2);
for(int i=;i<=n;i++)scanf("%d",a+i);
for(int i=;i<=n;i++)scanf("%d",b+i);
S=;T=*n+;
EC=-;
for(int i=;i<=n;i++){
addedge(S,i,,);
addedge(i,n+i,-a[i],);
addedge(i,n*+i,-b[i],);
addedge(n+i,T-,,);
addedge(n*+i,T-,,);
}
addedge(T-,T,,num1);
addedge(T-,T,,num2);
}
bool SPFA(){
int u,v;
for(u=S;u<=T;u++){
sp[u]=INF;
}
queue<int>q;
prev[S]=-;
q.push(S);
sp[S]=;
vis[S]=;
while(!q.empty()){
u=q.front();
vis[u]=;
q.pop();
for(edge *k=V[u];k;k=k->next){
v=k->t;
if(k->c>&&sp[u]+k->v<sp[v]){
sp[v]=sp[u]+k->v;
prev[v]=u;
path[v]=k;
if(vis[v]==){
vis[v]=;
q.push(v);
}
}
}
}
return sp[T]!=INF;
}
int argument(){
int i,cost=INF,flow=;
edge *e;
for(i=T;prev[i]!=-;i=prev[i]){
e=path[i];
if(e->c<cost)cost=e->c;
}
for(int i=T;prev[i]!=-;i=prev[i]){
e=path[i];
e->c-=cost;e->op->c+=cost;
flow+=e->v*cost;
}
return flow;
}
int maxcostflow(){
int Flow=;
while(SPFA()){
Flow+=argument();
}
return Flow;
}
int main(){
init();
printf("%d\n",-maxcostflow());
for(int i=;i<=n;i++){
for(edge *it=V[i+n];it;it=it->next){
if(it->t<=n&&it->c>)printf("%d ",i);
}
}
puts("");
for(int i=;i<=n;i++){
for(edge *it=V[i+*n];it;it=it->next){
if(it->t<=n&&it->c)printf("%d ",i);
}
}
return ;
}
Codeforces 730I [费用流]的更多相关文章
- Codeforces 362E 费用流
题意及思路:https://blog.csdn.net/mengxiang000000/article/details/52472696 代码: #define Hello the_cruel_wor ...
- Codeforces 708D 费用流 (呃我们的考试题)
NB的题目背景 输入输出一样 考试的时候貌似只有gzz一个人搞出来了 %gzz 思路: 分情况讨论 add(x,y,C,E) C是费用 E是流量 1. f>c add(x,y,2,inf),ad ...
- Codeforces 最大流 费用流
这套题目做完后,一定要反复的看! 代码经常出现的几个问题: 本机测试超时: 1.init函数忘记写. 2.addedge函数写成add函数. 3.边连错了. 代码TLE: 1.前向星边数组开小. 2. ...
- CodeForces 164C Machine Programming 费用流
Machine Programming 题目连接: http://codeforces.com/problemset/problem/164/B Descriptionww.co One remark ...
- Codeforces Gym 100002 E "Evacuation Plan" 费用流
"Evacuation Plan" Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/10 ...
- Codeforces Gym 101190M Mole Tunnels - 费用流
题目传送门 传送门 题目大意 $m$只鼹鼠有$n$个巢穴,$n - 1$条长度为$1$的通道将它们连通且第$i(i > 1)$个巢穴与第$\left\lfloor \frac{i}{2}\rig ...
- Codeforces 280D k-Maximum Subsequence Sum [模拟费用流,线段树]
洛谷 Codeforces bzoj1,bzoj2 这可真是一道n倍经验题呢-- 思路 我首先想到了DP,然后矩阵,然后线段树,然后T飞-- 搜了题解之后发现是模拟费用流. 直接维护选k个子段时的最优 ...
- BZOJ 3836 Codeforces 280D k-Maximum Subsequence Sum (模拟费用流、线段树)
题目链接 (BZOJ) https://www.lydsy.com/JudgeOnline/problem.php?id=3836 (Codeforces) http://codeforces.com ...
- Codeforces 362E Petya and Pipes 费用流建图
题意: 给一个网络中某些边增加容量,增加的总和最大为K,使得最大流最大. 费用流:在某条边增加单位流量的费用. 那么就可以2个点之间建2条边,第一条给定边(u,v,x,0)这条边费用为0 同时另一条边 ...
随机推荐
- python数据结构
. 数据结构¶ .1. 深入列表¶ 链表类型有很多方法,这里是链表类型的所有方法: list.append(x) 把一个元素添加到链表的结尾,相当于 a[len(a):] = [x] . list ...
- 防止sql注入
sqlmap 较专业的sql注入工具YII2 activeform 注意传过来的modle的rules规则 <?php$form=\yii\widgets\ActiveForm::begi ...
- C++ STL泛型编程——在ACM中的运用
学习过C++的朋友们应该对STL和泛型编程这两个名词不会陌生.两者之间的关系不言而喻,泛型编程的思想促使了STL的诞生,而STL则很好地体现了泛型编程这种思想.这次想简单说一下STL在ACM中的一些应 ...
- Python 模块chardet安装 setup.py
http://pypi.python.org/pypi/chardet#downloads 下载chardet-2.*.*.tar.gz:解压到site-package文件夹, Python及其一些模 ...
- 微信Oauth2.0鉴权 40029 问题
前阵子出了这个问题,具体表现为,在获得用户授权时,有时会出现 40029 code 无效或超时 问题.在网上查询后,大多数人说是因为微信请求了两次url,导致第二次失效,而第一次被终止了. 现在找到了 ...
- C/C++变量名与值的问题
首先说明变量名是不占空间的. 变量:用来标识一块内存空间,这块内存区域的值一般是可以被该的. 而const常量通常限定这一块内存区域的值是不可被更改的. 变量名:只是一个标识符,并不占内存空间.在c的 ...
- C++ operator 的一种不会的用法
自认为对C++比较熟悉,突然看到一些奇怪的代码(在看网上下载的代码Sockets): class SocketAddress { public: virtual ~SocketAddress() {} ...
- js 防止页面后退的方法
//防止页面后退 history.pushState(null, null, document.URL); window.addEventListener('popstate', function ( ...
- 修改msde登录方式,设置sa密码为空
md, 记不得msde怎么修改密码, 每次都要去baidu, 下了个鸟破软件,修改msde密码, 还流氓的安装了360, 写了个批处理,留在这里: net stop MSSQLSERVERreg ad ...
- C#调试器导航
本快速入门演示如何在 Visual Studio 调试会话中导航,以及如何在会话中查看和更改程序状态. 本 快速入门适用于不熟悉用 Visual Studio 进行调试的开发人员,以及要详细了解在 V ...