分析

这类问题的一遍描述,把一些对象分成两组,划分有一些代价,问最小代价。一般性的思路是,

把这两组看成是S点和T点,把划分的代价和割边的容量对应起来求最小割。

把S和可模版tem之间到达关系看作是属于核A,对称地,T对应B。模块tem安装在A上代价Ai,就是割断tem和T,连一条tem到T的容量为Ai的边。

相应地,对于Bi,连一条S到tem容量为Bi的边。当ai安装在A上,bi安装在B上,也就是s - ai, bi - t(-表示可到达),这时候如果有额外花费wi

那么ai - bi之间连上容量为wi的边,反过来bi和ai对换一下也是类似的。

输入很大,光是I/O就能优化1s,ISAP会更快。

/*********************************************************
* ------------------ *
* author AbyssalFish *
**********************************************************/
#include<cstdio>
#include<iostream>
#include<string>
#include<cstring>
#include<queue>
#include<vector>
#include<stack>
#include<vector>
#include<map>
#include<set>
#include<algorithm>
#include<cmath>
using namespace std; const int maxv = 2e4+, maxe = 4e5+maxv*;
int hd[maxv],to[maxe],nx[maxe],ec,cap[maxe];
#define eachEage int i = hd[u]; ~i; i = nx[i]
inline void add(int u,int v, int cp)
{
nx[ec] = hd[u];
to[ec] = v;
cap[ec] = cp;
hd[u] = ec++;
}
inline void Add(int u,int v,int cp)
{
add(u,v,cp); add(v,u,);
}
int lv[maxv], q[maxv];
bool vis[maxv];
int S,T;
bool bfs()
{
memset(vis,,sizeof(bool)*(T+));
int l = , r = ;
lv[q[r++] = S] = ;
vis[S] = true;
while(l<r){
int u = q[l++];
for(eachEage){
int v = to[i];
if(!vis[v] && cap[i]){
lv[q[r++] = v] = lv[u] + ;
vis[v] = true;
}
}
}
return vis[T];
} int cur[maxv]; int aug(int u,int a)
{
if(u == T || !a) return a;
int flow = ,f;
for(int &i = cur[u]; ~i; i = nx[i]){
int v = to[i];
if(lv[v] == lv[u]+ && (f = aug(v, min(a,cap[i])))){
flow += f; a -= f;
cap[i] -= f; cap[i^] += f;
if(!a) break;
}
}
return flow;
} int maxFlow()
{
int flow = ;
while(bfs()){
memcpy(cur,hd,sizeof(int)*(T+));
flow += aug(S,<<);
}
return flow;
} inline int read()
{
int ret; char c; while(c = getchar(),c<''||c>'');
ret = c-'';
while(c = getchar(),c>=''&&c<='') ret = ret* + c-'';
return ret;
} //#define LOCAL
int main()
{
#ifdef LOCAL
freopen("in.txt","r",stdin);
#endif
int n, m;
while(~scanf("%d%d",&n,&m)){
S = ; T = n+;
memset(hd,0xff,sizeof(int)*(T+)); ec = ;
for(int i = ; i <= n; i++){
Add(i,T,read());
Add(S,i,read());
}
for(int i = ; i < m; i++){
int a = read(),b = read(),w = read();
add(a,b,w); add(b,a,w);
}
printf("%d\n",maxFlow());
} return ;
}

最新文章

  1. POJ2096 Collecting Bugs
  2. iOS上传App Store报错:this action cannot be completed -22421 解决方案
  3. react-redux(2)
  4. 《利用python进行数据分析》读书笔记--第十章 时间序列(三)
  5. 泡泡堂、QQ堂游戏通信架构分析
  6. 163. Missing Ranges
  7. simhash类的使用
  8. android官方技术文档翻译——Case 标签中的常量字段
  9. 经典Console案例
  10. 设计模式 | 装饰模式(decorator)
  11. 不能完整读取txt文件问题
  12. (九) 主机增加打印(串口+ssh)
  13. Perl IO:随机读写文件
  14. 用IntelliJ IDEA 开发Spring+SpringMVC+Mybatis框架 分步搭建三:配置spring并测试
  15. 剑指offer-扑克牌顺子
  16. DHCP服务
  17. flask框架----flask中的wtforms使用
  18. JavaScript中的构造函数 renturn
  19. Postgresql 創建觸發器,刪除觸發器和 禁用觸發器
  20. Android下拉刷新完全解析

热门文章

  1. python之02数据类型学习-作业练习2
  2. (PHP)redis Hash(哈希)操作
  3. 洛谷P2700 逐个击破
  4. jmeter-逻辑控制器之 交替控制器(实现2个请求每次只执行其中一个)
  5. CF446B DZY Loves Modification 优先队列
  6. emmet缩写大全
  7. POJ1009 Edge Detection
  8. 浅谈ThreadLocal模式
  9. Win10家庭版打不开gpedit.msc
  10. java——super关键字、final关键字、throws关键字、访问控制