这题的思路我觉得five20巨佬讲的已经非常清晰了,所以就推荐一下他的题解,我就只放代码了
//It is made by HolseLee on 7th Feb 2018 //Luogu.org P1251 #include<cstdio> #include<cstring> #include<cstdlib> #include<cmath> #include<iostream> #include<queue> #include<algorithm> using namespace std; #define inf 1e12 const int N=20001; typedef long long ll; ll n,d1,d2,c1,c2,p; ll sta,endd,head[N]; ll cnt=1,ans,dis[N]; bool vis[N],inq[N]; struct Node{ ll to,val; ll cost,next; }edge[N<<2]; queue<ll>team; inline ll read() { char ch=getchar();ll num=0;bool flag=false; while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)flag=true;ch=getchar();} while(ch>=‘0‘&&ch<=‘9‘){num=num*10+ch-‘0‘;ch=getchar();} return flag?-num:num; } inline void add(ll x,ll y,ll z,ll c) { edge[++cnt].to=y; edge[cnt].val=z; edge[cnt].cost=c; edge[cnt].next=head[x]; head[x]=cnt; } inline void add_edge(ll x,ll y,ll z,ll c) {add(x,y,z,c);add(y,x,0,-c);} inline bool spfa() { for(ll i=sta;i<=endd;i++)dis[i]=inf; memset(inq,false,sizeof(inq)); team.push(endd);dis[endd]=0; inq[endd]=true; while(!team.empty()){ ll u=team.front();team.pop(); inq[u]=false; for(ll i=head[u];i!=-1;i=edge[i].next){ ll v=edge[i].to; if(edge[i^1].val&&dis[v]>dis[u]-edge[i].cost){ dis[v]=dis[u]-edge[i].cost; if(!inq[v]){ inq[v]=true; team.push(v); } } } } return dis[sta]<inf; } inline ll dfs(ll u,ll nowflow) { vis[u]=true; if(nowflow==0||u==endd)return nowflow; ll used=0; for(ll i=head[u];i!=-1;i=edge[i].next){ ll v=edge[i].to; if(!vis[v]&&edge[i].val&&dis[v]==dis[u]-edge[i].cost){ ll ka=dfs(v,min(nowflow,edge[i].val)); edge[i].val-=ka;edge[i^1].val+=ka; used+=ka;nowflow-=ka; if(nowflow==0)return used; } } return used; } void ready() { memset(head,-1,sizeof(head)); n=read();ll x; sta=0;endd=2*n+1; for(ll i=1;i<=n;i++){ x=read(); add_edge(sta,i+n,x,0); add_edge(i,endd,x,0);} p=read(); d1=read();c1=read(); d2=read();c2=read(); for(ll i=1;i<=n;i++){ add_edge(sta,i,inf,p); if(i+d1<=n)add_edge(i+n,i+d1,inf,c1); if(i+d2<=n)add_edge(i+n,i+d2,inf,c2); if(i+1<=n)add_edge(i,i+1,inf,0); } } void work() { while(spfa()){ vis[endd]=true; while(vis[endd]){ memset(vis,false,sizeof(vis)); ll ka=dfs(sta,inf); ans+=ka*dis[sta]; } } printf("%lld",ans); } int main() { ready(); work(); return 0; }
原文地址:https://www.cnblogs.com/cytus/p/8427437.html
时间: 2024-10-03 09:35:24