您的位置:首页 > 理论基础 > 计算机网络

hdu 3917 Road constructions【网络流-全闭包】

2014-11-07 14:41 99 查看
原文链接:http://acm.hdu.edu.cn/showproblem.php?pid=3917

分析:建立源汇点是s,t;以公司为节点,将每个公司与s连接权值为税收;

将每个公司与t连接权值为所施工程花费总和;若公司A与公司B之间有联系

(A公司施工路径尾端=B公司施工路径前端这A与B有联系,题目以有陈诉)

这将AB连接权值为INF。

代码示例:

#include<stdio.h>

#include<string.h>

#include<algorithm>

#include<iostream>

#include<queue>

#define Lh 200000

#define Le 200000

#define max 1000000000

using namespace std;

typedef struct

{

int to;

int w;

int next;

}node;

typedef struct

{

int star,end;

int id;

}nodf;

typedef struct

{

int x;

int t;

}DEP;

node E[Le];

nodf e[Le];

DEP fir,nex;

int head[Lh],headx[Lh],deep[Lh],cnt;

int cost[Le];

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

{

E[++cnt].to=b;

E[cnt].w=c;

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

head[a]=cnt;

E[++cnt].to=a;

E[cnt].w=0;

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

head[b]=cnt;

}

int min(int x,int y)

{

return x<y?x:y;

}

int bfs(int s,int t,int n)

{

memset(deep,255,sizeof(deep));

queue<DEP>Q;

fir.x=s;

fir.t=0;

deep[s]=0;

Q.push(fir);

while(!Q.empty())

{

fir=Q.front();

Q.pop();

for(int i=head[fir.x];i;i=E[i].next)

{

nex.x=E[i].to;

nex.t=fir.t+1;

if(deep[nex.x]!=-1||!E[i].w)

continue;

deep[nex.x]=nex.t;

Q.push(nex);

}

}

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

headx[i]=head[i];

return deep[t]!=-1;

}

int dfs(int s,int t,int flow)

{

if(s==t)

return flow;

int newflow=0;

for(int i=headx[s];i;i=E[i].next)

{

headx[s]=i;

int to=E[i].to;

int w=E[i].w;

if(!w||deep[to]!=deep[s]+1)

continue;

int temp=dfs(to,t,min(w,flow-newflow));

newflow+=temp;

E[i].w-=temp;

E[i^1].w+=temp;

if(newflow==flow)

break;

}

if(!newflow)deep[s]=0;

return newflow;

}

int Dinic(int s,int t,int m)

{

int sum=0;

while(bfs(s,t,m))

{

sum+=dfs(s,t,max);

}

return sum;

}

int main()

{

int n,m,z;

int s,t;

int x,sum;

while(~scanf("%d%d",&n,&m))

{

if(m==0&&n==0)

break;

memset(head,0,sizeof(head));

memset(cost,0,sizeof(cost));

cnt=1,sum=0;

s=m+1,t=m+2;

for(int i=1;i<=m;i++)

{

scanf("%d",&x);

ADD(s,i,x);

sum+=x;

}

scanf("%d",&z);

for(int i=1;i<=z;i++)

{

scanf("%d%d%d%d",&e[i].star,&e[i].end,&e[i].id,&x);

cost[e[i].id]+=x;

}

for(int i=1;i<=z;i++)

for(int j=1;j<=z;j++)

{

if(e[i].id!=e[j].id&&e[i].end==e[j].star)

{

ADD(e[i].id,e[j].id,max);

}

}

for(int i=1;i<=m;i++)

{

ADD(i,t,cost[i]);

}

sum=sum-Dinic(s,t,200000-10);

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

}

return 0;

}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: