POJ3469 Dual Core CPU 最大流dinic

题意:双核电脑处理任务。

每个任务在每个核中处理的cost已知,并且已知如果某两个任务在不同核时的extra cost。

思路:最大流最小割。难点在于构图。

构图时,把核A作为源点,把核B作为汇点。

任务作为中间节点。cost作为单向边。

特别地,对于“如果某两个任务在不同核时的extra cost。”作为两个任务的双向边。

这样构成的图用dinic求最大流。结果则是答案。

不得不感慨最大流真是好用。

#include<iostream>
#include<string>
using namespace std;
const int N=20015,M=200015;
const int inf=99999999;
int n,m;
int que[N];
int level[N];
struct Edge
{
int v,w,next,re;
}edge[4*N+2*M];
int visit[N];
int edgehead[N];
int k=1;
void addedge(int u,int v,int w,int w0)
{
edge[k].v=v;
edge[k].w=w;
edge[k].next=edgehead[u];
edge[k].re=k+1;
edgehead[u]=k++;
edge[k].v=u;
edge[k].w=w0;
edge[k].next=edgehead[v];
edge[k].re=k-1;
edgehead[v]=k++;
}
bool bfs()
{
memset(visit,0,sizeof(visit));
memset(level,0,sizeof(level));
int head=1,tail=1;
que[tail++]=n+1;
visit[n+1]=true;
level[n+1]=0;
while(head<tail)
{
int now=que[head++];
if(now==n+2)
{
return true;
}
for(int i=edgehead[now];i!=0;i=edge[i].next)
{
int to=edge[i].v;
if(!visit[to]&&edge[i].w>0)
{
que[tail++]=to;
visit[to]=true;
level[to]=level[now]+1;
}
}
}
return false;
}
int dinic(int k,int sum)
{
if(k==n+2)
return sum;
int os=sum;
for(int i=edgehead[k];sum>0&&i!=0;i=edge[i].next)
{
int to=edge[i].v;
if(level[to]==level[k]+1&&edge[i].w>0)
{
int a=dinic(to,(sum<edge[i].w?sum:edge[i].w));
edge[i].w-=a;
edge[edge[i].re].w+=a;
sum-=a;
}
}
return os-sum;
}
int main()
{
scanf("%d%d",&n,&m);
int a,b,c;
for(int i=1;i<=n;i++)
{
scanf("%d%d",&a,&b);
addedge(n+1,i,a,0);
addedge(i,n+2,b,0);
}


for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&a,&b,&c);
addedge(a,b,c,c);
}
int ans=0;
while(bfs())
{
ans+=dinic(n+1,inf);
}
printf("%d\n",ans);


return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值