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题告诉我,进步虽然不明显,但是只要坚持努力的 ...
随机推荐
- Command 传参的几种方式
Command可以根据CommandParameter传参 关键代码 public ICommand SubmitCommand => _submitCommand; private Relay ...
- 1-5-vim编辑器的使用
第1章 vim主要模式介绍,vim命令模式. 1.1 确保系统已经安装了VIM工具 [root@panda ~]# rpm -qf `which vim` [root@panda ~]# rpm ...
- Qt打开外部程序和文件夹需要注意的细节(注意QProcess的空格问题,以及打开本地文件时,需要QUrl::fromLocalFile才可以)
下午写程序中遇到几个小细节,需要在这里记录一下. ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 QProcess *process = new QProcess(this ...
- 【python】python调用adb
本期分享下python如何调用adb: 1.导入os模块 import os 2.python中调用adb命令语法 print("显示机型信息:") os.system('adb ...
- 使用IntelliJ IDEA开发SpringMVC网站(五)博客文章管理
原文:使用IntelliJ IDEA开发SpringMVC网站(五)博客文章管理 摘要 通过对博客文章的管理,实现外键操作. 目录[-] 八.博客文章管理 1.查看文章 2.添加博客 3 ...
- 队列读取器代理 遇到错误 Row handle is invalid
原文:队列读取器代理 遇到错误 Row handle is invalid 今天测试在发布中更改表名称,在发布数据库更改后重新发布这个表. 但是原来的表在订阅没有删除,不小心插入数据到原表中,队列读取 ...
- C# 查农历 阴历 阳历 公历 节假日
原文:C# 查农历 阴历 阳历 公历 节假日 using System;using System.Collections.Generic;using System.Text; namespace ca ...
- C# System.Windows.Forms.WebBrowser中判断浏览器内核和版本
参考 [完美]原生JS获取浏览器版本判断--支持Edge,IE,Chrome,Firefox,Opera,Safari,以及各种使用Chrome和IE混合内核的浏览器 利用js来判断 namespac ...
- Android零基础入门第87节:Fragment添加、删除、替换
前面一起学习了Fragment的创建和加载,以及其生命周期方法,那么接下来进一步来学习Fragment的具体使用,本期先来学习Fragment添加.删除.替换. 一.概述 在前面的学习中,特别是动态加 ...
- 使用QPainter的drawPixmap()绘制多幅图片 good
众所周知,使用QLabel的setPixmap()就可以将图片显示出来,做视屏解码后显示也可以如此.但是为何我今天还要费力使用基函数drawPixmap()来做绘图?理由有这么些吧: 1.使用QLab ...