最大流最小割经典例题_POJ3469 Dual Core CPU 最大流 最小割

该题目要求解决CPU程序执行分布问题,通过最小化交互代价。利用最大流最小割理论,将CPU视为源点s和汇点t,建立网络流模型,通过ISAP算法找到最小割,确定程序在CPU间的最优分布,实现总消耗最小。
摘要由CSDN通过智能技术生成

题意:CPU有两个,程序可以在里面执行,并分别告知在两个CPU内的工作时间,随后告知有些CPU是要进行相互交互合作的,所以它们之间要交互数据,如果两个程序在不同的CPU里运行那么将会有较高的交互代价,问如何安排程序执行的分布,使得总的消耗最小,给出最小消耗。

分析:这题原来想DP过的,发现交互程序对木有最优子结构,所以DP不可能,最后才发现这是道最大流最小割问题的经典例题。为何想到是割?因为两个CPU之间的程序是相互隔离的,所以可以把两个CPU看成s和t,形成了割的核心,剩下的就是由s向各个程序连边,由各个程序向t连边,程序相互交互的也要连边,由此构成网络流的模型,求此网络的最小割,即最大流。割必定分隔s和t两个CPU,所以有些程序必然与s相连,有些必然与t相连,相互通过最小割隔离,从而形成解决方案。

ISAP算法,敲得已经非常熟练鸟。

#include

#define INF 0x7fffffff

#define MAXN 20005

#define MAXM 900000

typedef struct

{

int vv,cap,next;

}Edge;

Edge edge[MAXM];

int head[MAXN],gap[MAXN],v[MAXN],q[MAXN],cnt,n;

void build(int a,int b,int c)

{

edge[cnt].next=head[a];

edge[cnt].vv=b;

edge[cnt].cap=c;

head[a]=cnt++;

edge[cnt].next=head[b];

edge[cnt].vv=a;

edge[cnt].cap=0;

head[b]=cnt++;

}

void BFS()

{

int i,u,h,t,vt;

q[0]=n+1;

h=t=0;

while(h<=t)

{

u=q[h++];

for(i=head[u];i>=0;i=edge[i].next)

{

vt=edge[i].vv;

if(v[vt]==n+2&&!edge[i].cap)

{

q[++t]=vt;

v[vt]=v[u]+1;

gap[v[vt]]++;

}

}

}

}

int ISAP(int u,int sum)

{

int s,t,minv=n+1,i,vt,tt;

if(u==n+1) return sum;

s=sum;

for(i=head[u];i>=0;i=edge[i].next)

{

vt=edge[i].vv;

tt=edge[i].cap;

if(tt>0)

{

if(v[u]==v[vt]+1)

{

t=ISAP(vt,tt

edge[i].cap-=t;

edge[i^1].cap+=t;

sum-=t;

if(!sum||v[0]>=n+2) break;

}

minv=minv

}

}

if(s==sum)

{

gap[v[u]]--;

if(!gap[v[u]]) v[0]=n+2;

gap[v[u]=minv+1]++;

}

return s-sum;

}

int main()

{

int i,maxflow,m,a,b,c;

maxflow=cnt=0;

scanf("%d%d",&n,&m);

for(i=0;i<=n+1;i++)

{

head[i]=-1;

gap[i]=0;

v[i]=n+2;

}

gap[0]++;

v[n+1]=0;

for(i=1;i<=n;i++)

{

scanf("%d%d",&a,&b);

build(0,i,a);

build(i,n+1,b);

}

while(m--)

{

scanf("%d%d%d",&a,&b,&c);

build(a,b,c);

build(b,a,c);

}

BFS();

while(v[0]

printf("%d\n",maxflow);

return 0;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值