POJ 3469 最小割 Dual Core CPU
2015-09-09 11:50
357 查看
题意:
一个双核CPU上运行N个模块,每个模块在两个核上运行的费用分别为Ai和Bi。
同时,有M对模块需要进行数据交换,如果这两个模块不在同一个核上运行需要额外花费。
求运行N个模块的最小费用。
分析:
这是一个集合划分问题,将这两个模块划分成两个集合,一个集合中的模块在核A上运行,一个在核B上运行。
增加一个源点S和汇点T,每个模块分别和源点和汇点连一条边,容量为在该核上运行的花费。
然后在两个模块对之间连容量为额外花费的双向边。
图中的一个割就对应一个集合的划分,最小割就是最小的总费用。
代码君
一个双核CPU上运行N个模块,每个模块在两个核上运行的费用分别为Ai和Bi。
同时,有M对模块需要进行数据交换,如果这两个模块不在同一个核上运行需要额外花费。
求运行N个模块的最小费用。
分析:
这是一个集合划分问题,将这两个模块划分成两个集合,一个集合中的模块在核A上运行,一个在核B上运行。
增加一个源点S和汇点T,每个模块分别和源点和汇点连一条边,容量为在该核上运行的花费。
然后在两个模块对之间连容量为额外花费的双向边。
图中的一个割就对应一个集合的划分,最小割就是最小的总费用。
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <vector> #include <queue> using namespace std; const int maxn = 20000 + 10; const int INF = 0x3f3f3f3f; int n, s, t; int N, M; struct Edge { int from, to, cap, flow; Edge(int u, int v, int c, int f):from(u), to(v), cap(c), flow(f) {} }; vector<Edge> edges; vector<int> G[maxn]; void init() { edges.clear(); for(int i = 0; i < n; i++) G[i].clear(); } void AddEdge(int u, int v, int c) { edges.push_back(Edge(u, v, c, 0)); edges.push_back(Edge(v, u, 0, 0)); int m = edges.size(); G[u].push_back(m - 2); G[v].push_back(m - 1); } bool vis[maxn]; int d[maxn], cur[maxn]; bool BFS() { memset(vis, false, sizeof(vis)); vis[s] = true; queue<int> Q; Q.push(s); d[s] = 0; while(!Q.empty()) { int u = Q.front(); Q.pop(); for(int i = 0; i < G[u].size(); i++) { Edge& e = edges[G[u][i]]; int v = e.to; if(!vis[v] && e.cap > e.flow) { vis[v] = true; d[v] = d[u] + 1; Q.push(v); } } } return vis[t]; } int DFS(int u, int a) { if(u == t || a == 0) return a; int flow = 0, f; for(int& i = cur[u]; i < G[u].size(); i++) { Edge& e = edges[G[u][i]]; int v = e.to; if(d[v] == d[u] + 1 && (f = DFS(v, min(a, e.cap - e.flow))) > 0) { flow += f; e.flow += f; a -= f; edges[G[u][i]^1].flow -= f; if(a == 0) break; } } return flow; } int Maxflow() { int flow = 0; while(BFS()) { memset(cur, 0, sizeof(cur)); flow += DFS(s, INF); } return flow; } int main() { while(scanf("%d%d", &N, &M) == 2) { n = N + 2; init(); s = 0, t = N + 1; for(int i = 1; i <= N; i++) { int a, b; scanf("%d%d", &a, &b); AddEdge(s, i, a); AddEdge(i, t, b); } while(M--) { int a, b, w; scanf("%d%d%d", &a, &b, &w); AddEdge(a, b, w); AddEdge(b, a, w); } printf("%d\n", Maxflow()); } return 0; }
代码君
相关文章推荐
- 关于BaseAdapter在listView中的使用
- “服务器推”技术的应用
- 一个比较完整的Inno Setup 安装脚本 - 增加了对ini文件设置的功能
- java垃圾回收机制和内存泄露
- What is VEX ?
- how to install protobuff python
- .Net使用微軟自帶的用戶驗證和登錄授權
- cocos2dx编程 之如何获取节点的中心点坐标
- 文章标题
- 项目管理_团队协作
- 使用streaming window函数统计用户不同时间段平均消费金额等指标
- 使用streaming window函数统计用户不同时间段平均消费金额等指标
- 使用streaming window函数统计用户不同时间段平均消费金额等指标
- dispatch_async & dispatch_sync理解
- 使用streaming window函数统计用户不同时间段平均消费金额等指标
- 用boost locale库进行字符集转换的问题
- Nginx负载均衡配置实例详解
- CreaAndroid【1】用注解和反射实现Json自动化解析
- android 下拉刷新的时候,有的手机会把分割线给下拉拖出来,处理divider解决
- mysql索引总结----mysql 索引类型以及创建