#include<string.h>
#include<cstdio>
#include<algorithm>
#include<limits.h>
#include<queue>
using namespace std;
const int M=420;
const int inf=0x3f3f3f3f;
struct aa
{
int u,v,r,next;
} edge[888888];
int cnt,dis[M],s,f,n,m,cost[M],pre[M],head[M];
void add(int u,int v,int r)
{
edge[cnt].v=v;
edge[cnt].u=u;
edge[cnt].r=r;
edge[cnt].next=pre[u];
pre[u]=cnt++;
edge[cnt].v=u;
edge[cnt].u=v;
edge[cnt].r=0;
edge[cnt].next=pre[v];
pre[v]=cnt++;
}
bool bfs()//建立层次图
{
memset(dis,0,sizeof(dis));
dis[s]=1;
queue<int>que;
que.push(s);
while(!que.empty())
{
int u=que.front();
que.pop();
for(int i=pre[u]; i!=-1; i=edge[i].next)
{
int v=edge[i].v;
int r=edge[i].r;
if(dis[v]==0&&r>0)
{
dis[v]=dis[u]+1;
que.push(v);
}
}
}
return dis[f]>=1;
}
int dfs(int now,int Min)//多路增广
{
int a;
if(now==f)
return Min;
int cost=0;
for(int &i=head[now]; i!=-1; i=edge[i].next)
{
int v=edge[i].v;
int r=edge[i].r;
if(dis[v]==dis[now]+1&&r>0 &&(a=dfs(v,min(Min-cost,r))))
{
edge[i].r-=a;
edge[i^1].r+=a;
cost+=a;//汇聚各个方向的流量
if(Min==cost)//当某几个方向的流量相加等于当前最大流量的时候就无法对别的路进行增广了
break;
}
}
return cost;//返回当前汇聚的流量
}
int Max_f()
{
int sum=0;
while(bfs())
{
for(int i=0; i<=2*n; i++)//当前弧优化
head[i]=pre[i];
while(int temp=dfs(s,inf))//一次bfs多次增广
sum+=temp;
}
return sum;
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
scanf("%d%d",&s,&f);
memset(pre,-1,sizeof(pre));
f=f+n;
cnt=0;
for(int i=1; i<=n; i++)
{
scanf("%d",&cost[i]);
add(i,n+i,cost[i]);
}
while(m--)
{
int u,v;
scanf("%d%d",&u,&v);
add(n+u,v,inf);
add(v+n,u,inf);
}
int ans=Max_f();
printf("%d\n",ans);
}
}
最大流dinic算法的优化模板 当前弧优化,多路增广
最新推荐文章于 2020-11-29 23:39:56 发布