POJ 3469 - Dual Core CPU(Dinic最大流)
来源:互联网 发布:网络推手的盈利模式 编辑:程序博客网 时间:2024/06/16 22:02
【题意】
有N个任务,A与B两个核心,任务i若在A上执行需代价Ai,在B上执行需代价Bi
还有M个特殊关系,表示若任务a与任务b不在同一机器上执行,需额外代价C
第一行输入N<=20000,M<=200000
接下来N行是Ai Bi
接下来M行是特殊关系a b
求完成所有任务最小代价
【题解】
网络流建模,超级源sr到每个任务i有容量为Ai的单向边,每个任务i到超级汇dr有容量为Bi的单向边,特殊对a b之间有双向边容量为C,最小割即为答案。
有最大流最小割定理可求最大流。
使用Dinic+多路增广(必选)+当前弧(可选)
根据本蒟蒻的代码实验,裸Dinic会T,加多路增广4200ms,加当前弧3.6ms,所以多路增广很关键,具体实现就是dfs时把他上一个点传过来的可增广流量尽量用完,并且如果耗尽了自己的的出口残量,在这次的层次图中就不在尝试这个点。具体见代码。
还有,这个代码比较奇葩,我是从汇点向源点搜的,但是搜出来的路还是从sr到dr增广,看代码就明白。
#include<cstdio>#include<cstdlib>#include<cstring>#include<climits>#include<iostream>#include<vector>#include<algorithm>using namespace std;const int NMAX=20000,MMAX=200000,VMAX=NMAX+100,EMAX=(NMAX*2+MMAX)*2+100;struct Edge{ int h,t,f; Edge *ne,*re;};struct EList{ Edge *head; static void next(Edge* &p){ p=p->ne; } static void uniteRev(){ pool[cnt-1].re=pool+cnt-2; pool[cnt-2].re=pool+cnt-1; } void push(int t,int f){ pool[cnt].t=t; pool[cnt].f=f; pool[cnt].ne=head; head=pool+cnt++; } static Edge pool[EMAX]; static int cnt;};int EList::cnt;Edge EList::pool[EMAX];EList eg[VMAX];namespace dinic{ int depg[VMAX],sr,dr; Edge *nh[VMAX]; bool bfs(){ static int que[VMAX]; memcpy(nh,eg,(dr+1)*sizeof(EList));//当前弧预处理 int head=0,rear=0; memset(depg,-1,(dr+1)*sizeof(int)); for(depg[que[rear++]=sr]=0;head!=rear;){ int now=que[head++]; for(Edge *it=eg[now].head;it;EList::next(it)) if(!~depg[it->t] && it->f) depg[que[rear++]=it->t]=depg[now]+1; } return depg[dr]!=-1; } int dfs(int x,int f){ static Edge *head[VMAX]; if(depg[x]==0) return f;//找到源点 int ft,w=0; for(Edge *&it=nh[x];it;EList::next(it)){ if(depg[x]-1==depg[it->t] && it->re->f) if(ft=dfs(it->t,min(f-w,it->re->f))){ it->re->f-=ft; it->f+=ft; w+=ft; } if(w==f) break;//如果可增广流量耗尽,则退出 } if(!w) depg[x]=-1;//如果不可增广,即出口残量耗尽,则不再访问此点 return w; } long long calc(int _sr,int _dr){ long long res=0; sr=_sr;dr=_dr; for(;bfs();) for(int ft;ft=dfs(dr,INT_MAX);) res+=ft; return res; }}int main(){ freopen("in.txt","r",stdin); for(int n,m;~scanf("%d%d",&n,&m);){ EList::cnt=0; memset(eg,0,sizeof eg); for(int i=0;i<n;i++){ int a,b; scanf("%d%d",&a,&b); eg[0].push(i+1,a); eg[i+1].push(0,0); EList::uniteRev(); eg[i+1].push(n+1,b); eg[n+1].push(i+1,0); EList::uniteRev(); } for(int i=0;i<m;i++){ int h,t,f; scanf("%d%d%d",&h,&t,&f); eg[h].push(t,f); eg[t].push(h,f); EList::uniteRev(); } printf("%lld\n",dinic::calc(0,n+1)); } return 0;}
- POJ 3469 Dual Core CPU---dinic求最大流
- POJ 3469 - Dual Core CPU(Dinic最大流)
- POJ 3469 Dual Core CPU <Dinic + 最小割 + 最大流>
- Poj 3469 Dual Core CPU【最小割最大流-----Dinic】
- POJ3469 Dual Core CPU 最大流dinic
- POJ 3469 Dual Core CPU(最大流最小割定理,Dinic)
- POJ 3469-Dual Core CPU(Dinic 最大流/最小割算法)
- poj 3469 Dual Core CPU (最大流)
- poj 3469 Dual Core CPU 最大流建图思想 dinic 弧优化很重要
- POJ 3469 Dual Core CPU(最小割-Dinic)
- poj 3469 Dual Core CPU(dinic算法)
- poj 3469 Dual Core CPU (最小割->最大流)
- POJ 3469 Dual Core CPU 最大流最小割
- POJ -- 3469 Dual Core CPU (最大流,最小割)
- poj 3469 Dual Core CPU 最大流最小割定理
- poj 3469 Dual Core CPU (最小割最大流)
- poj 3469 Dual Core CPU 最大流-最小割
- POJ 3469->Dual Core CPU(最大流最小割问题)
- UIWebView的一些总结
- 一个普普通通的计算机研究生找工作的感悟
- ios下获取所有实体/虚拟网卡的信息,并以此判断设备所处的网络状态
- msvcp100d.dll
- hdu2574(一个数的不同的质数因子个数)
- POJ 3469 - Dual Core CPU(Dinic最大流)
- 黑马程序员_线程
- Linux下NC扫描TCP,UDP端口
- (考前水题)LA2191 裸树状数组
- 奇数和偶数
- 数据上报分析
- socket状态变化图
- LIRe 源代码分析 6:检索(ImageSearcher)[以颜色布局为例]
- JSTL自定义函数完成ACL即时认证