厉害了我的哥。。这建图。。
感谢http://www.cnblogs.com/rausen/p/4176729.html
这个建图的重点在于把需求和剩下的毛巾分开。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<queue> #define maxv 2050 #define maxn 1050 #define maxe 1000050 #define inf 2000000000 using namespace std; int n,a,b,f,fa,fb,N[maxn],dis[maxv],nume=1,g[maxv],pree[maxv],prev[maxv],s,t; bool vis[maxv]; queue <int> q; struct edge { int v,f,c,nxt; }e[maxe]; void addedge(int u,int v,int f,int c) { e[++nume].v=v;e[nume].f=f;e[nume].c=c;e[nume].nxt=g[u];g[u]=nume; e[++nume].v=u;e[nume].f=0;e[nume].c=-c;e[nume].nxt=g[v];g[v]=nume; } void build() { s=0;t=2*n+1; for (int i=1;i<=n;i++) { addedge(s,i,N[i],0);addedge(i+n,t,N[i],0); addedge(s,i+n,inf,f); if (i+a+1<=n) addedge(i,i+a+n+1,inf,fa); if (i+b+1<=n) addedge(i,i+b+n+1,inf,fb); } for (int i=1;i<=n-1;i++) addedge(i+n,i+n+1,inf,0); } bool spfa() { for (int i=s;i<=t;i++) {pree[i]=prev[i]=-1;dis[i]=inf;vis[i]=false;} q.push(s);vis[s]=true;dis[s]=0; while (!q.empty()) { int head=q.front();q.pop(); for (int i=g[head];i;i=e[i].nxt) { int v=e[i].v; if ((e[i].f) && (dis[v]>dis[head]+e[i].c)) { dis[v]=dis[head]+e[i].c; pree[v]=i;prev[v]=head; if (!vis[v]) {q.push(v);vis[v]=true;} } } vis[head]=false; } if (dis[t]==inf) return false; return true; } int dinic() { int u=t,low=inf; while (u!=s) { low=min(low,e[pree[u]].f); u=prev[u]; } u=t; while (u!=s) { e[pree[u]].f-=low;e[pree[u]^1].f+=low; u=prev[u]; } return dis[t]*low; } int main() { scanf("%d%d%d%d%d%d",&n,&a,&b,&f,&fa,&fb); for (int i=1;i<=n;i++) scanf("%d",&N[i]); build(); int min_cost=0; while (spfa()) min_cost+=dinic(); printf("%d\n",min_cost); return 0; }