建边有技巧啊,要拆点。
网络流建边的核心规律就是多做题一定是从源点到汇点,根据此构建模型即可。
\(dinic\) 实现最小费用流
/*
@Date : 2019-07-16 11:10:42
@Author : Adscn (adscn@qq.com)
@Link : https://www.cnblogs.com/LLCSBlog
*/
#include<bits/stdc++.h>
using namespace std;
#define IL inline
#define RG register
#define gi getint()
#define gc getchar()
#define File(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout)
IL int getint()
{
RG int xi=0;
RG char ch=gc;
bool f=0;
while(ch<'0'|ch>'9')ch=='-'?f=1:f,ch=gc;
while(ch>='0'&ch<='9')xi=(xi<<1)+(xi<<3)+ch-48,ch=gc;
return f?-xi:xi;
}
template<typename T>
IL void pi(T k,char ch=0)
{
if(k<0)k=-k,putchar('-');
if(k>=10)pi(k/10,0);
putchar(k%10+'0');
if(ch)putchar(ch);
}
const int inf=2147483647,N=2007;
int S=0,T;
struct edge{int v,nxt,flow,w;}e[N<<2];
int head[N<<1],cnt;
int cur[N<<1];
inline void add(int u,int v,int flow,int cost){e[cnt]=(edge){v,head[u],flow,cost};head[u]=cnt++;}
inline void link(int u,int v,int flow,int cost){add(u,v,flow,cost);add(v,u,0,-cost);}
int dis[N<<1];
bool vis[N<<1];
int spfa()
{
memset(dis,127,sizeof dis);
memset(vis,0,sizeof vis);
static int Q[N<<1],l,r;
dis[Q[l=r=0]=S]=0;
while(l<=r)
{
int p=Q[l++];
vis[p]=0;
for(int i=head[p];~i;i=e[i].nxt)
{
int v=e[i].v;
if(dis[v]>dis[p]+e[i].w&&e[i].flow)
{
dis[v]=dis[p]+e[i].w;
if(!vis[v])Q[++r]=v,vis[v]=1;
}
}
}
return dis[T]<1e9;
}
long long ans;
int dfs(int p,int restflow)
{
if(p==T||restflow==0)return restflow;
int sumflow=0;
vis[p]=1;
for(int &i=cur[p],flow;(~i)&&restflow;i=e[i].nxt)
{
int v=e[i].v;
if(vis[v]==0&&e[i].flow&&dis[v]==dis[p]+e[i].w&&(flow=dfs(v,min(restflow,e[i].flow))))
{
sumflow+=flow,restflow-=flow;
e[i].flow-=flow,e[i^1].flow+=flow;
ans+=1ll*flow*e[i].w;
}
}
vis[p]=0;
return sumflow;
}
void dinic(){while(spfa())memcpy(cur,head,sizeof head),dfs(S,inf);}
int main(void)
{
#ifndef ONLINE_JUDGE
File("file");
#endif
int n=gi;T=n*2+1;
memset(head,-1,sizeof head);
for(int i=1;i<=n;++i)
{
int x=gi;
link(S,i,x,0);
link(i+n,T,x,0);
}
int newcost=gi,fastday=gi,fastcost=gi,slowday=gi,slowcost=gi;
for(int i=1;i<=n;++i)
{
if(i<n)link(i,i+1,inf,0);
if(i+slowday<=n)link(i,i+n+slowday,inf,slowcost);
if(i+fastday<=n)link(i,i+n+fastday,inf,fastcost);
link(S,i+n,inf,newcost);
}
dinic();
pi(ans);
return 0;
}