●洛谷 1251 餐巾计划问题
●题链:
https://www.luogu.org/problemnew/show/1251
●题解:
一点启示:建图时要考虑到流量问题,即为了方便使用最小费用最大流算法,要把流量最大时为最终目的考虑进建图。
拆点,每天拆为两个点i, i',表示每天开始和每天结束
(s,i,ai,P):在第i天最多买ri个餐巾,花费为P;
(i,t,ai,0):第i天要用ai块餐巾;
(s,i',ai,0):第i天用剩的ai块旧餐巾;
(i',i+M,INF,F):第i天的旧餐巾送到快洗部,花费为F;
(i',i+N,INF,S):第i天的旧餐巾送到慢洗部,花费为S;
(i,i+1,INF,0):第i天的没用的餐巾可以留到第i+1天去用。
SPFA费用流:
#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#define MAXN 2050
#define INF 0x3f3f3f3f
using namespace std;
struct Edge{
int to[MAXN*12],cap[MAXN*12],cot[MAXN*12],nxt[MAXN*12],head[MAXN*2],ent;
void Init(){
ent=2; memset(head,0,sizeof(head));
}
void Adde(int u,int v,int w,int c){
to[ent]=v; cap[ent]=w; cot[ent]=c;
nxt[ent]=head[u]; head[u]=ent++;
to[ent]=u; cap[ent]=0; cot[ent]=-c;
nxt[ent]=head[v]; head[v]=ent++;
}
int Next(int i,bool type){
return type?head[i]:nxt[i];
}
}E;
int a[MAXN];
int Day,P,M,F,N,S,SS,TT;
int idx(int i,int k){
return i+Day*k;
}
bool spfa(long long &cost){
static bool inq[MAXN*2];
static int dis[MAXN*2],p[MAXN*2],flow[MAXN*2];
memset(dis,0x3f,sizeof(dis));
queue<int>q;
q.push(SS); inq[SS]=1; dis[SS]=0; flow[SS]=INF;
while(!q.empty()){
int u=q.front(); q.pop(); inq[u]=0;
for(int i=E.Next(u,1);i;i=E.Next(i,0)){
int v=E.to[i];
if(!E.cap[i]||dis[v]<=dis[u]+E.cot[i]) continue;
dis[v]=dis[u]+E.cot[i]; p[v]=i; flow[v]=min(flow[u],E.cap[i]);
if(!inq[v]) inq[v]=1,q.push(v);
}
}
if(dis[TT]==INF) return 0;
int u=TT; cost+=1ll*flow[TT]*dis[TT];
while(u!=SS){
E.cap[p[u]]-=flow[TT];
E.cap[p[u]^1]+=flow[TT];
u=E.to[p[u]^1];
}
return 1;
}
long long Mincost_Maxflow(){
long long cost=0;
while(spfa(cost));
return cost;
}
int main()
{
E.Init();
scanf("%d",&Day); SS=2*Day+1; TT=2*Day+2;
for(int i=1;i<=Day;i++){
scanf("%d",&a[i]);
E.Adde(SS,idx(i,1),a[i],0);
E.Adde(idx(i,0),TT,a[i],0);
}
scanf("%d%d%d%d%d",&P,&M,&F,&N,&S);
for(int i=1,_i;i<=Day;i++){
E.Adde(SS,idx(i,0),a[i],P);
_i=i+M; if(_i<=Day) E.Adde(idx(i,1),idx(_i,0),INF,F);
_i=i+N; if(_i<=Day) E.Adde(idx(i,1),idx(_i,0),INF,S);
}
for(int i=1;i<=Day;i++){
if(i!=Day) E.Adde(idx(i,0),idx(i+1,0),INF,0);
}
long long ans=Mincost_Maxflow();
printf("%lld",ans);
return 0;
}
ZKW(dinic实现)费用流:
#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#define MAXN 2050
#define INF 0x3f3f3f3f
using namespace std;
struct Edge{
int to[MAXN*12],cap[MAXN*12],cot[MAXN*12],nxt[MAXN*12],head[MAXN*2],ent;
void Init(){
ent=2; memset(head,0,sizeof(head));
}
void Adde(int u,int v,int w,int c){
to[ent]=v; cap[ent]=w; cot[ent]=c;
nxt[ent]=head[u]; head[u]=ent++;
to[ent]=u; cap[ent]=0; cot[ent]=-c;
nxt[ent]=head[v]; head[v]=ent++;
}
int Next(int i,bool type){
return type?head[i]:nxt[i];
}
}E;
int a[MAXN],cur[MAXN*2],dis[MAXN*2];
int Day,P,M,F,N,S,SS,TT;
int idx(int i,int k){
return i+Day*k;
}
bool spfa(){
static bool inq[MAXN*2];
memset(dis,0x3f,sizeof(dis));
queue<int>q;
q.push(TT); inq[TT]=1; dis[TT]=0;
while(!q.empty()){
int u=q.front(); q.pop(); inq[u]=0;
for(int i=E.Next(u,1);i;i=E.Next(i,0)){
int v=E.to[i];
if(!E.cap[i^1]||dis[v]<=dis[u]+E.cot[i^1]) continue;
dis[v]=dis[u]+E.cot[i^1];
if(!inq[v]) inq[v]=1,q.push(v);
}
}
return dis[SS]<INF;
}
int dfs(int u,int reflow){
if(u==TT||reflow==0) return reflow;
int flowout=0,f,d=dis[u]; dis[u]=INF;
for(int &i=cur[u];i;i=E.Next(i,0)){
int v=E.to[i];
if(d!=dis[v]+E.cot[i]||!E.cap[i]) continue;
f=dfs(v,min(reflow,E.cap[i]));
flowout+=f; E.cap[i^1]+=f;
reflow-=f; E.cap[i]-=f;
if(!reflow) break;
}
return flowout;
}
long long ZKW_Mincost(){
long long cost=0;
while(spfa()){
memcpy(cur,E.head,sizeof(E.head));
cost+=1ll*dis[SS]*dfs(SS,INF);
}
return cost;
}
int main()
{
E.Init();
scanf("%d",&Day); SS=2*Day+1; TT=2*Day+2;
for(int i=1;i<=Day;i++){
scanf("%d",&a[i]);
E.Adde(SS,idx(i,1),a[i],0);
E.Adde(idx(i,0),TT,a[i],0);
}
scanf("%d%d%d%d%d",&P,&M,&F,&N,&S);
for(int i=1,_i;i<=Day;i++){
E.Adde(SS,idx(i,0),a[i],P);
_i=i+M; if(_i<=Day) E.Adde(idx(i,1),idx(_i,0),INF,F);
_i=i+N; if(_i<=Day) E.Adde(idx(i,1),idx(_i,0),INF,S);
}
for(int i=1;i<=Day;i++){
if(i!=Day) E.Adde(idx(i,0),idx(i+1,0),INF,0);
}
long long ans=ZKW_Mincost();
printf("%lld",ans);
return 0;
}
Do not go gentle into that good night.
Rage, rage against the dying of the light.
————Dylan Thomas

浙公网安备 33010602011771号