题目大意:
有n个月,第i个月需要ui件货物,每个单位的货物再第i个月的价格是di,仓库容量为s,每放在仓库贮存1个月,每个单位的货物就要使用m元,若当月卖了出去则不用付.
解题思路:
赤裸裸的费用流
其实网络流最重要的就是建图 图建好了套模版 下面是建图方式: 1.建立源点与每个月连接,流量为无穷大,费用为di. 2.建立汇点与每个月连接,流量为ui,费用为0. 3.第i个月与第i+1个月连接,流量为s,费用为m. 原因: 1.可以买进无数件,费用当然就是价格 2.最大流,这ui肯定要流的,然后费用在源点与每个月之间就已经”买单”了. 3.仓库容量是s,费用是m,然后货物可以给下个月用源程序:
#include#include #include using namespace std;struct node{ int x,to,f,c,next;}e[205];int d[55],pre[55],last[55],cnt=-1,ans,n,m,S,s,t; bool v[55];void add(int u,int v,int c,int w){ e[++cnt].x=u;e[cnt].to=v;e[cnt].f=w;e[cnt].c=c;e[cnt].next=last[u];last[u]=cnt; e[++cnt].x=v;e[cnt].to=u;e[cnt].f=-w;e[cnt].c=0;e[cnt].next=last[v];last[v]=cnt;}bool spfa(){ queue q; for (int i=s;i<=t;i++) d[i]=1e9; memset(pre,-1,sizeof(pre)); memset(v,0,sizeof(v)); d[s]=0;q.push(s);v[s]=1; while(q.size()) { int u=q.front();q.pop();v[u]=0; for (int i=last[u];~i;i=e[i].next) if (e[i].c&&d[e[i].to]>d[u]+e[i].f) { d[e[i].to]=d[u]+e[i].f; pre[e[i].to]=i; if (!v[e[i].to]) { v[e[i].to]=1; q.push(e[i].to); } } } return d[t]!=1e9;}void mcf(){ int i=t,minn=1e9; while (~pre[i]) { minn=min(e[pre[i]].c,minn); i=e[pre[i]].x; } ans+=d[t]*minn; i=t; while (~pre[i]) { e[pre[i]].c-=minn; e[pre[i]^1].c+=minn; i=e[pre[i]].x; } return;}int spf(){ while (spfa()) mcf(); return ans;}//上面的都是模版//我就不解释了int main(){ memset(last,-1,sizeof(last));//初始化 scanf("%d%d%d",&n,&m,&S); s=0;t=n+1;//建立源点汇点 for (int i=1;i<=n;i++) { int x; scanf("%d",&x); add(i,t,x,0);//连接(每个月与汇点) } for (int i=1;i<=n;i++) { int x; scanf("%d",&x); add(s,i,1e9,x);//连接(源点与每个月) } for (int i=1;i