Codeforces 730I:Olympiad in Programming and Sports(最小费用流)
http://codeforces.com/problemset/problem/730/I
题意:有n个人参加两种比赛,其中每个人有两个参加比赛的属性,如果参加了其中的一个比赛,那么不能参加另一个比赛,每种比赛有一个参加的限制人数,求让两种比赛的属性值最大的方案。
思路:如果往网络流方面想,就挺容易想到最小费用流的。
学习了一个技巧:把费用设为负,最后再反过来,就可以求最大费用流了。
将S和每个人相连,容量为1, 费用为0,再把每个人和T1点相连(代表第一个属性),容量为1,费用为-a[i],每个人和T2点相连(代表第二个属性),容量为1,费用为-b[i],再把T1和T相连,容量为p,T2和T相连,容量为s。
因为一些粗心调了N久。
#include <bits/stdc++.h>
using namespace std;
#define N 3010
#define INF 0x3f3f3f3f
struct Edge {
int u, v, cap, cost, nxt;
} edge[N*];
int head[N], a[N], b[N], tot, S, T, vis[N], dis[N], ans, pre[N]; void Add(int u, int v, int cap, int cost) {
edge[tot] = (Edge) {u, v, cap, cost, head[u]}; head[u] = tot++;
edge[tot] = (Edge) {v, u, , -cost, head[v]}; head[v] = tot++;
} bool SPFA() {
queue<int> que;
que.push(S);
memset(dis, INF, sizeof(dis));
memset(vis, , sizeof(vis));
int flow = INF;
dis[S] = ; vis[S] = ; pre[S] = -;
while(!que.empty()) {
int u = que.front(); que.pop();
vis[u] = ;
for(int i = head[u]; ~i; i = edge[i].nxt) {
int v = edge[i].v, w = edge[i].cost;
if(edge[i].cap && dis[v] > dis[u] + w) {
dis[v] = dis[u] + w;
pre[v] = i;
flow = min(flow, edge[i].cap);
if(!vis[v]) { vis[v] = ; que.push(v); }
}
}
}
if(dis[T] == INF) return false;
ans -= flow * dis[T];
int u = T;
while(u != S) {
edge[pre[u]].cap -= flow;
edge[pre[u]^].cap += flow;
u = edge[pre[u]].u;
}
return true;
} int main() {
int n, q, p;
scanf("%d%d%d", &n, &p, &q);
for(int i = ; i <= n; i++) scanf("%d", a + i);
for(int i = ; i <= n; i++) scanf("%d", b + i);
S = , T = n + ; int T1 = n + , T2 = n + , c1 = , c2 = ;
memset(head, -, sizeof(head)); tot = ;
for(int i = ; i <= n; i++) {
Add(S, i, , ); Add(i, T1, , -a[i]); Add(i, T2, , -b[i]);
}
Add(T1, T, p, ); Add(T2, T, q, );
ans = ;
while(SPFA()) ;
for(int u = ; u <= n; u++) {
for(int i = head[u]; ~i; i = edge[i].nxt) {
int v = edge[i].v;
if(edge[i].cap == ) {
if(v == T1) a[++c1] = u;
if(v == T2) b[++c2] = u;
}
}
}
printf("%d\n", ans);
for(int i = ; i <= c1; i++) printf("%d ", a[i]); puts("");
for(int i = ; i <= c2; i++) printf("%d ", b[i]); puts("");
return ;
}
Codeforces 730I:Olympiad in Programming and Sports(最小费用流)的更多相关文章
- Codeforces 937A - Olympiad
A. Olympiad 题目链接:http://codeforces.com/problemset/problem/937/A time limit per test 1 second memory ...
- Codeforces 730I [费用流]
/* 不要低头,不要放弃,不要气馁,不要慌张 题意: 给两行n个数,要求从第一行选取a个数,第二行选取b个数使得这些数加起来和最大. 限制条件是第一行选取了某个数的条件下,第二行不能选取对应位置的数. ...
- CodeForces 222D - Olympiad
第一行给出两个个数字k和n,第二三行分别有k个数字,求将第二.三行之间的数字相互组合,求最多有多少个组合的和不小于n 纯粹暴力 #include <iostream> #include & ...
- Codeforces 最大流 费用流
这套题目做完后,一定要反复的看! 代码经常出现的几个问题: 本机测试超时: 1.init函数忘记写. 2.addedge函数写成add函数. 3.边连错了. 代码TLE: 1.前向星边数组开小. 2. ...
- 2016-2017 ACM-ICPC, NEERC, Southern Subregional Contest (Online Mirror) in codeforces(codeforces730)
A.Toda 2 思路:可以有二分来得到最后的数值,然后每次排序去掉最大的两个,或者3个(奇数时). /************************************************ ...
- 2016-2017 ACM-ICPC, NEERC, Southern Subregional Contest
A. Toda 2 按题意模拟即可. #include <bits/stdc++.h> using namespace std ; typedef pair < int , int ...
- 模拟费用流 & 可撤销贪心
1. CF730I Olympiad in Programming and Sports 大意: $n$个人, 第$i$个人编程能力$a_i$, 运动能力$b_i$, 要选出$p$个组成编程队, $s ...
- codeforces675D
Tree Construction CodeForces - 675D During the programming classes Vasya was assigned a difficult pr ...
- OUC_Summer Training_ DIV2_#16 725
今天做了这两道题真的好高兴啊!!我一直知道自己很渣,又贪玩不像别人那样用功,又没有别人有天赋.所以感觉在ACM也没有学到什么东西,没有多少进步.但是今天的B题告诉我,进步虽然不明显,但是只要坚持努力的 ...
随机推荐
- 活锁(livelock) 专题
活锁(livelock) 活锁指的是任务或者执行者没有被阻塞,由于某些条件没有满足,导致一直重复尝试,失败,尝试,失败. 活锁和死锁的区别在于,处于活锁的实体是在不断的改变状态,所谓的“活”, 而处于 ...
- UWP入门(十)--获取文件属性
原文:UWP入门(十)--获取文件属性 重要的 API StorageFile.GetBasicPropertiesAsync StorageFile.Properties StorageItemCo ...
- 利用开源软件 Hugin 实现照片的景深合成,使用开源软件 enfuse 做照片的曝光合成
http://blog.csdn.net/liyuanbhu/article/details/53573847 http://blog.csdn.net/liyuanbhu/article/detai ...
- Qt设置窗体的透明度: setWindowOpacity
在Qt中,设置窗体透明度的函数有:void setWindowOpacity(qreal level) 特性: 透明度的有效范围从1.0(完全不透明)到0.0(完全透明的). 默认情况下,此属 ...
- 在Linux中如何利用backtrace信息解决问题
在Linux中如何利用backtrace信息解决问题 一.导读 在程序调试过程中如果遇到程序崩溃死机的情况下我们通常多是通过出问题时的栈信息来找到出错的地方,这一点我们在调试一些高级编程语言程序的时候 ...
- javascript 实现ajax
AJAX 英文名称 Asynchronous JavaScript and XML即异步的 JavaScript 和 XML AJAX 是与服务器交换数据并更新部分网页一门无刷新技术构建自己的ajax ...
- java关键字之synchronized
1.synchronized可以用了修饰一个普通方法,或者代码块,这个时候synchronized锁定的是当前对象,只要有一个线程在访问对应的方法或代码块,其他线程必须等待.2.synchronize ...
- 血的教训--如何正确使用线程池submit和execute方法
血的教训之背景:使用线程池对存量数据进行迁移,但是总有一批数据迁移失败,无异常日志打印 凶案起因 听说parallelStream并行流是个好东西,由于日常开发stream串行流的场景比较多,这次 ...
- Redis---学习笔记(更新中)
一.基本命令 #查看所有键 keys * #查看指定键 keys key #查看模糊键 keys ke* keys ke? keys ke[a-z] keys ke\? #判断键是否存在 exists ...
- SpringBoot从入门到精通十一(SpringBoot文件上传的两种方法)
前言 在企业级项目开发过程中,上传文件是最常用到的功能.SpringBoot集成了SpringMVC,当然上传文件的方式跟SpringMVC没有什么出入. 本章目标 使用SpringBoot项目完成单 ...