【做题】POJ3469 Dual Core CPU——第一道网络流
刚学了Dinic就开始做题,然后就崩了。
题意:若干个任务,可以放在两个CPU中任意一个上完成,各有一定代价。其中又有若干对任务,如果它们不在同一个CPU上完成,会产生额外代价。最小化并输出代价。
一开始的想法是吧一个任务拆开成两个点(受2-sat的影响),然后就发现自己没法做了。首先,需要保证由同一个任务拆成的两个点只流过一个,这就会使最大流变成费用流。(我不会费用流)其次,难以满足第二个要求。后来一想,网络流与2-sat建图的区别在于网络流的状态表现在边的流量上(是否满流),而2-sat表现于同组点的取舍上。同样地,我也不能在2-sat和单位网络之间划等号。前者的作用是生成一个可行的方案,后者则是最优解。
那么,如上文所述,我们见图时要把状态表现在流量上。先不考虑额外代价,对于一个任务,它应该接着两条边表示两种选择。于是,可以从题解上抄到想到从超级源点向它建一条容量为第一种选择代价的边,从它向超级汇点建一条容量为第二种选择的边。此时这张图的最小割就是最优解。
然后考虑额外代价。存在这个代价当且仅当两个任务处割掉了位置不同的边。

左上图:两个任务处割掉了位置不同的边
然后,我们只要在两个任务之间建一条容量为额外代价的双向边就可以了。这时因为割的性质就能把额外代价考虑其中了。并且,这不会影响其他情况。
故我们完成了建图,然后就只需要贴板子卡常就可以了。
令人震惊的是:时间复杂度O(n^2*m)。代码已自动过滤快读、register、inline
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <queue>
using namespace std;
const int N = , M = , INF = <<;
int n,m,s,t;
struct edge {
int la,b,cap,flo;
edge(int la=,int b=,int cap=,int flo=):
la(la),b(b),cap(cap),flo(flo){};
}con[M<<];
int tot,fir[N],cur[N],d[N];
void add(int from,int to,int cap,int cap_back=) {
con[++tot] = edge(fir[from],to,cap);
fir[from] = tot;
con[++tot] = edge(fir[to],from,cap_back);
fir[to] = tot;
}
bool vis[N];
void init() {
for (int i=;i<=n;++i) cur[i] = fir[i];
memset(vis,,sizeof vis);
}
bool bfs() {
init();
queue<int> q;
while (!q.empty()) q.pop();
q.push(s);
d[s] = ;
vis[s] = ;
for (int pos = q.front();!q.empty();q.pop(),pos = q.front()) {
for (int i=fir[pos];i;i=con[i].la) if (!vis[con[i].b]) {
if (con[i].cap>con[i].flo) {
d[con[i].b] = d[pos] + ;
vis[con[i].b] = ;
q.push(con[i].b);
}
}
}
return vis[t];
}
int dfs(int x,int imp) {
if (x == t||!imp) return imp;
int expo = , tmp;
for (int &i=cur[x];i;i=con[i].la) if (d[con[i].b] == d[x] + ) {
tmp = dfs(con[i].b,min(imp,con[i].cap-con[i].flo));
if (tmp > ) {
con[i].flo += tmp;
con[i^].flo -= tmp;
expo += tmp;
imp -= tmp;
if (!imp) break;
}
}
return expo;
}
int solve() {
int res = ;
while (bfs()) {
res += dfs(s,INF);
}
return res;
}
int main() {
int a,b,w;
while (scanf("%d%d",&n,&m)!=EOF) {
memset (fir,,sizeof fir);
tot = ;
for (int i=;i<=n;++i) {
scanf("%d%d",&a,&b);
add(n+,i,a);
add(i,n+,b);
}
for (int i=;i<=m;++i) {
scanf("%d%d",&a,&b,&w);
add(a,b,w,w);
}
s = n+, t = n+;
n += ;
printf("%d\n",solve());
}
return ;
}
小结:这可以说是对网络流模型的理解还不够。
【做题】POJ3469 Dual Core CPU——第一道网络流的更多相关文章
- poj3469 Dual Core CPU
Dual Core CPU Time Limit: 15000MS Memory Limit: 131072K Total Submissions: 25576 Accepted: 11033 ...
- poj3469 Dual Core CPU——最小割
题目:http://poj.org/problem?id=3469 最小割水题(竟然没能1A): 代码如下: #include<iostream> #include<cstdio&g ...
- POJ3469 Dual Core CPU(最小割)
形象生动的最小割.. #include<cstdio> #include<cstring> #include<queue> #include<algorith ...
- POJ3469 Dual Core CPU(最小割)
题意:给你n个模块,每个模块在A核花费为ai,在B核跑花费为bi,然后由m个任务(ai,bi,wi),表示如果ai,bi不在同一个核上跑,额外的花费为wi,求最小的花费. 一开始想的时候以为是费用流, ...
- POJ 3469.Dual Core CPU 最大流dinic算法模板
Dual Core CPU Time Limit: 15000MS Memory Limit: 131072K Total Submissions: 24830 Accepted: 10756 ...
- Dual Core CPU
Dual Core CPU Time Limit: 15000MS Memory Limit: 131072K Total Submissions: 20935 Accepted: 9054 Case ...
- poj 3469 Dual Core CPU【求最小割容量】
Dual Core CPU Time Limit: 15000MS Memory Limit: 131072K Total Submissions: 21453 Accepted: 9297 ...
- POJ 3469 Dual Core CPU Dual Core CPU
Time Limit: 15000MS Memory Limit: 131072K Total Submissions: 23780 Accepted: 10338 Case Time Lim ...
- HDU-1532 Drainage Ditches,人生第一道网络流!
Drainage Ditches 自己拉的专题里面没有这题,网上找博客学习网络流的时候看到闯亮学长的博客然后看到这个网络流入门题!随手一敲WA了几发看讨论区才发现坑点! 本题采用的是Edmonds-K ...
随机推荐
- sqlserver备份还原数据库时报占用错误
.做项目时遇到这种情形:原来的test_dev数据库,想复制出test_ft供测试用.此时备份test_dev出test_backup文件,想直接还原成test_ft时会报占用错误. 还原数据库:Th ...
- faces
install Boost [boost_1_65_1-msvc-14.0-32.exe]BOOST_LIBRARYDIR=D:\_softwares_kits\boost_1_65_1\lib32- ...
- 软工网络15团队作业4——Alpha阶段敏捷冲刺5.0
1.每天举行站立式会议,提供当天站立式会议照片一张. 2.项目每个成员的昨天进展.存在问题.今天安排. 成员 昨天已完成 今天计划完成 郭炜埕 完善新建话题界面 实现前端各界面的跳转连接 郑晓丽 进行 ...
- python random函数
.random模块方法说明 random.random()函数是这个模块中最常用的方法了,它会生成一个随机的浮点数,范围是在0.0~1.0之间. random.uniform()正好弥补了上面函数的不 ...
- Hive 数仓中常见的日期转换操作
(1)Hive 数仓中一些常用的dt与日期的转换操作 下面总结了自己工作中经常用到的一些日期转换,这类日期转换经常用于报表的时间粒度和统计周期的控制中 日期变换: (1)dt转日期 to_date(f ...
- Mysql相关技术细节整理
一.错误日志相关 1.mysql错误日志所在位置 windows下,错误日志文件一般在安装目录下的data目录下.扩展名是.err的文件,也可以打开安装目录下的my.ini文件检查一下linux下,错 ...
- linux 安装python3 date更新
http://linux.51yip.com/ ntpdate -u ntp.aliyun.com 更新时间 centos 默认是有 python的,是2.7.5的 重启网络的命令 -- sys ...
- Caddy – 方便够用的 HTTPS server 新手教程
最近发现了一个 golang 开发的 HTTP server,叫做 Caddy,它配置起来十分简便,甚至可以 28 秒配置好一个支持 http2 的 server ,而且对各种 http 新特性都支持 ...
- 清明 DAY 1
数学基础 Part 1. 高精度计算 Part 2. 模意义下的运算 mod 对一个数取模,其实就是取余数 注意: • 无除法运算 • ...
- node.js学习(一)
一.assert assert.deepEqual(actual, expected[, message]) 测试 actual 参数与 expected 参数是否深度相等. 原始值使用相等运算符(= ...