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

一开始想的时候以为是费用流,但想着想着觉得,这么大的数据量绝对不可能是费用流。最后发现它是一个最小割模型。实际上就是要将网络里的模块划分成s-t两个点集,然后我们合适的构造一下边就可以使得对应的最小割就是我们的答案,构造的方法是这样的:当模块属于A集的时候,花费为ai,所以就从向t连一条ai的边,而当模块属于B集的时候,花费为bi,所以就由s连一条向bi的边。然后对于每个任务,当ai,bi不同的时候花费为mi,所以就由ai,bi连两条容量为wi的边,跑一下最大流就可以得出对应的最小花费了。代码将《挑战》上的模板化了一下,以后用起来会方便点吧~

#pragma warning(disable:4996)
#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<cmath>
#include<queue>
#define ll long long
#define maxn 23500
#define maxe 1000000
#define inf 1100000000
using namespace std; struct Edge
{
int u, v, cap;
int nxt;
}edge[maxe]; int head[maxn];
int n, m; struct Dicnic
{
int level[maxn];
int iter[maxn];
int add;
void init(){
add = 0; memset(head, -1, sizeof(head));
memset(iter, -1, sizeof(iter));
}
void insert(int u, int v, int c){
edge[add].u = u; edge[add].v = v; edge[add].cap = c;
edge[add].nxt = head[u]; head[u] = add++;
edge[add].u = v; edge[add].v = u; edge[add].cap = 0;
edge[add].nxt = head[v]; head[v] = add++;
}
void bfs(int s){
memset(level, -1, sizeof(level));
queue<int> que;
level[s] = 0;
que.push(s);
while (!que.empty()){
int v = que.front(); que.pop();
for (int i = head[v]; i != -1; i = edge[i].nxt){
Edge &e = edge[i];
if (e.cap > 0 && level[e.v] < 0){
level[e.v] = level[v] + 1;
que.push(e.v);
}
}
}
} int dfs(int v, int t, int f){
if (v == t) return f;
for (int &i = iter[v]; i != -1; i = edge[i].nxt){
Edge &e = edge[i]; Edge &reve = edge[i ^ 1];
if (e.cap > 0 && level[v] < level[e.v]){
int d = dfs(e.v, t, min(f, e.cap));
if (d>0){
e.cap -= d; reve.cap += d;
return d;
}
}
}
return 0;
} int max_flow(int s, int t){
int flow = 0;
for (;;){
bfs(s);
if (level[t] < 0) return flow;
memcpy(iter, head, sizeof(iter));
int f;
while ((f = dfs(s, t, inf))>0){
flow += f;
}
}
}
}net; int a[maxn], b[maxn]; int main()
{
while (cin >> n >> m){
net.init();
int s = 0, t = n + 1;
for (int i = 1; i <= n; i++) {
scanf("%d", a + i); scanf("%d", b + i);
net.insert(i, t, a[i]);
net.insert(s, i, b[i]);
}
int ui, vi, wi;
for (int i = 0; i < m; i++){
scanf("%d%d%d", &ui, &vi, &wi);
net.insert(ui, vi, wi);
net.insert(vi, ui, wi);
}
printf("%d\n", net.max_flow(s,t));
}
return 0;
}

POJ3469 Dual Core CPU(最小割)的更多相关文章

  1. poj3469 Dual Core CPU——最小割

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

  2. POJ 3469 Dual Core CPU (最小割建模)

    题意 现在有n个任务,两个机器A和B,每个任务要么在A上完成,要么在B上完成,而且知道每个任务在A和B机器上完成所需要的费用.然后再给m行,每行 a,b,w三个数字.表示如果a任务和b任务不在同一个机 ...

  3. 【网络流#8】POJ 3469 Dual Core CPU 最小割【ISAP模板】 - 《挑战程序设计竞赛》例题

    [题意]有n个程序,分别在两个内核中运行,程序i在内核A上运行代价为ai,在内核B上运行的代价为bi,现在有程序间数据交换,如果两个程序在同一核上运行,则不产生额外代价,在不同核上运行则产生Cij的额 ...

  4. poj 3469 Dual Core CPU——最小割

    题目:http://poj.org/problem?id=3469 最小割裸题. 那个限制就是在 i.j 之间连双向边. 根据本题能引出网络流中二元关系的种种. 别忘了写 if ( x==n+1 ) ...

  5. poj 3469 Dual Core CPU 最小割

    题目链接 好裸的题....... 两个cpu分别作为源点和汇点, 每个cpu向元件连边, 权值为题目所给的两个值, 如果两个元件之间有关系, 就在这两个元件之间连边, 权值为消耗,这里的边应该是双向边 ...

  6. poj3469 Dual Core CPU

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

  7. POJ3469 Dual Core CPU(最小割)

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

  8. 【做题】POJ3469 Dual Core CPU——第一道网络流

    刚学了Dinic就开始做题,然后就崩了. 题意:若干个任务,可以放在两个CPU中任意一个上完成,各有一定代价.其中又有若干对任务,如果它们不在同一个CPU上完成,会产生额外代价.最小化并输出代价. 一 ...

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

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

随机推荐

  1. char const*, char*const, const char *const的区别

    C++标准规定,const关键字放在类型或变量名之前等价的.所以,const char*和 char const*是一样的. const char*   //常量指针---指向常量的指针----指针指 ...

  2. windows下找不到strings.h

    头文件用的strings.h,换成string.h就好了.但是以前的Linux系统下用strings.h,strerror都能正常编译,怎么样能正常使用strings.h linux系统下的库问题跟w ...

  3. VS中制作安装文件

    第一步先来建一个最简单的Windows窗体应用程序,并为项目命名为WinFormTest,解决方案为WinFormSetup 第二步在窗体Form中添加一个按钮并在按钮事件中添加代码,只做测试因此简单 ...

  4. oracle分区表(整理)

    Oracle 表分区 早在8.0.5版本中,Oracle就将范围分区技术引入,现在分区功能已经越来越强大,包括支持扩展分区功能.Interval分区.外键分区.模拟列分区.以及分区建议器等.那么,分区 ...

  5. MicrosoftProjectOxford 微软牛津计划

    光学字符识别 上传本地图片或者提供一个图片URL,查看光学字符识别的演示. 视觉特征分析 上传本地图片或者提供一个图片URL,查看视觉特征分析的演示. 缩略图 上传本地图片或者提供一个图片URL,查看 ...

  6. Object-c 语法 - 头文件引用(@class/#import/#include)

    一. Objective-C 中 #import 和 #include 的区别 预编译指令 Objective-C:#import:由gcc编译器支持 C,C++:#include 在 Objecti ...

  7. R统计图

    主题:R统计图 作者:luomg 关键字:统计,R,ggplot2 1.什么是统计图? 统计图:统计图是从数据到几何对象的图形属性的一个映射 砖石重量对价格的散点图 qplot(carat,price ...

  8. IOS之UIView的tag学习

    tag是UIView的一个属性,而且要求tag值唯一.父视图可以通过tag来找到一个子视图 UIView *redView = [[UIView alloc]initWithFrame:CGRectM ...

  9. java 判断两个数是否异号

    java 整型int占4个字节32位,两个数异或后移动31位判断结果,如果是1则异号,如果是0则同号 public class ShowEnviromentViarible { public stat ...

  10. Android -- 与WEB交互在同一个会话Session中通信

    Session与Cookie Cookie和Session都为了用来保存状态信息,都是保存客户端状态的机制,它们都是为了解决HTTP无状态的问题而所做的努力. Session可以用Cookie来实现, ...