您的位置:首页 > 其它

POJ 3469 Dual Core CPU【最小割】

2012-07-30 22:00 295 查看
题意: 计算机里配置了双核的CPU, 有 N 个原件, 知道了在每个原件在 每个CPU 上的 耗费,其中有 M 对原件需要协同工作,并且有协同工作的耗费,如果这些对原件是在同一个CPU上工作的话,就不计算协同工作的耗费。

分析:

建图:

把两个CPU 分别看成是 源点和汇点。

从源点 到 每个顶点连接一条 容量为 AI 的边,

从每个顶点 到 汇点 连接一条容量为 BI 的边,

如果 两个原件具有协同工作关系,就在两个原件之间连接一条 容量为 w 的双向边。

求出的最小割即为最小费用, 而最小割可以通过求最大流来求得。

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define clr(x)memset(x,0,sizeof(x))
#define min(a,b)(a)<(b)?(a):(b)
const int INF=0x1f1f1f1f;
const int maxn=20005;
const int maxm=800005;
struct node
{
int c,next,to;
}e[maxm];
int tot;
int head[maxn];
void add(int s,int u,int flow)
{
e[tot].to=u;
e[tot].c=flow;
e[tot].next=head[s];
head[s]=tot++;
}
int max_flow(int st,int end,int n)
{
int numh[maxn],h[maxn],curedge[maxn],pre[maxn];
int cur_flow,maxflow=0,u,tmp,neck,i;
clr(h);   clr(numh);
memset(pre,0xff,sizeof(pre));
for(i=1;i<=n;i++)
curedge[i]=head[i];
numh[0]=n;
u=st;
while(h[st]<n)
{
if(u==end)
{
cur_flow=INF;
for(i=st;i!=end;i=e[curedge[i]].to)
if(cur_flow>e[curedge[i]].c)
{
neck=i;
cur_flow=e[curedge[i]].c;
}
for(i=st;i!=end;i=e[curedge[i]].to)
{
tmp=curedge[i];
e[tmp].c-=cur_flow;
e[tmp^1].c+=cur_flow;
}
maxflow+=cur_flow;
u=neck;
}
for(i=curedge[u];i!=-1;i=e[i].next)
if(e[i].c&&h[u]==h[e[i].to]+1)
break;
if(i!=-1)
{
curedge[u]=i;
pre[e[i].to]=u;
u=e[i].to;
}
else
{
if(--numh[h[u]]==0) break;
curedge[u]=head[u];
for(tmp=n,i=head[u];i!=-1;i=e[i].next)
if(e[i].c)
tmp=min(tmp,h[e[i].to]);
h[u]=tmp+1;
++numh[h[u]];
if(u!=st)
u=pre[u];
}
}
return maxflow;
}
int main()
{
int flow,a,b,w,i,n,m;
while(scanf("%d%d",&n,&m)!=EOF)
{
tot=0;
memset(head,0xff,sizeof(head));
for(i=2;i<=n+1;i++)
{
scanf("%d%d",&a,&b);
add(1,i,a);
add(i,1,0);
add(i,n+2,b);
add(n+2,i,0);
}
while(m--)
{
scanf("%d%d%d",&a,&b,&w);
add(a+1,b+1,w);
add(b+1,a+1,w);
}
flow=max_flow(1,n+2,n+2);
printf("%d\n",flow);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: