刚学了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——第一道网络流的更多相关文章

  1. poj3469 Dual Core CPU

    Dual Core CPU Time Limit: 15000MS   Memory Limit: 131072K Total Submissions: 25576   Accepted: 11033 ...

  2. poj3469 Dual Core CPU——最小割

    题目:http://poj.org/problem?id=3469 最小割水题(竟然没能1A): 代码如下: #include<iostream> #include<cstdio&g ...

  3. POJ3469 Dual Core CPU(最小割)

    形象生动的最小割.. #include<cstdio> #include<cstring> #include<queue> #include<algorith ...

  4. POJ3469 Dual Core CPU(最小割)

    题意:给你n个模块,每个模块在A核花费为ai,在B核跑花费为bi,然后由m个任务(ai,bi,wi),表示如果ai,bi不在同一个核上跑,额外的花费为wi,求最小的花费. 一开始想的时候以为是费用流, ...

  5. POJ 3469.Dual Core CPU 最大流dinic算法模板

    Dual Core CPU Time Limit: 15000MS   Memory Limit: 131072K Total Submissions: 24830   Accepted: 10756 ...

  6. Dual Core CPU

    Dual Core CPU Time Limit: 15000MS Memory Limit: 131072K Total Submissions: 20935 Accepted: 9054 Case ...

  7. poj 3469 Dual Core CPU【求最小割容量】

    Dual Core CPU Time Limit: 15000MS   Memory Limit: 131072K Total Submissions: 21453   Accepted: 9297 ...

  8. POJ 3469 Dual Core CPU Dual Core CPU

    Time Limit: 15000MS   Memory Limit: 131072K Total Submissions: 23780   Accepted: 10338 Case Time Lim ...

  9. HDU-1532 Drainage Ditches,人生第一道网络流!

    Drainage Ditches 自己拉的专题里面没有这题,网上找博客学习网络流的时候看到闯亮学长的博客然后看到这个网络流入门题!随手一敲WA了几发看讨论区才发现坑点! 本题采用的是Edmonds-K ...

随机推荐

  1. Sitecore CMS中查看标准字段

    什么是标准字段? 标准字段是字段及其字段组的集合,用于包含有关Sitecore中项目的可配置元数据.Sitecore中继承自“标准模板”模板的任何项目都将包含这些字段. 可以在“标准模板”模板项找到/ ...

  2. WebConfig类

    package com.ssm.yjblogs.config; import java.util.ArrayList; import java.util.List; import java.util. ...

  3. Python pyodbc安装

    1)下面这个链接找个适合自己python版本的文件下载下来 https://pypi.org/project/pyodbc/#files 2)放到scripts下面 3) 在scripts路径上输入c ...

  4. 20165305 学习基础和C语言基础调查

    学习基础和C语言基础调查 <优秀的教学方法---做教练与做中学>心得 在<优秀的教学方法---做教练与做中学>文章中又一次提到了"做教练"这一学习方法,因为 ...

  5. C# 制作软件启动界面

    制作一个软件的启动界面 1.新建一个工程,将默认生成界面作为启动界面. 2.添加一个Label和ProgressBar还有Timer控件 注意:在ProgressBar控件中需要设置它的style  ...

  6. php获取字符串长度函数strlen和mb_strlen

    php获取字符串长度函数strlen和mb_strlencount() - 计算数组中的单元数目,或对象中的属性个数strlen — 获取字符串长度,一个汉字为3个字符mb_strlen() - 获取 ...

  7. 新做了块avr开发板--tft屏研究用

    2010-05-04 14:03:00 测试效果不错,使用也方便.

  8. 同行span标签设置display:inline-block;overflow:hidden垂直对齐问题

    1 问题描述:一个div包含 三个span 当span2 类样式设置如下图时,将导致垂直方向不对齐的情况 2解决方案: 将前面的也设置同样的样式 overflow:hidden; display:in ...

  9. markdown错误和问题

    一,同步预览插件崩了 emmmmm……插件崩了,好滴 http://markdownpad.com/faq.html#livepreview-directx 上网下载插件 完美运行~ 二.emmmmm ...

  10. ubuntu_查看software

    感谢原博主的分享 ubuntu安装和查看已安装 说明:由于图形化界面方法(如Add/Remove... 和Synaptic Package Manageer)比较简单,所以这里主要总结在终端通过命令行 ...