HDU 6118 度度熊的交易計劃 最大費用可行流
阿新 • • 發佈:2017-08-16
while cost inf nod logs c++ clu 答案 cpp
題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=6118
題意:中文題
分析:
最小費用最大流,首先建立源點 s
,與超級匯點 t
。因為生產一個商品需要花費 a[i]
元,且上限為 b[i]
,所以我們從 s
向這些點之間連一條容量為 b[i]
,費用為 a[i]
的邊。同樣的道理,出售一個商品可以賺到 c[i]
元,最多出售 d[i]
個,於是我們從這些點向 t
連一條容量為 d[i]
,費用為 -c[i]
的邊。最後所有的公路也是花費,從 u
到 v
連接一條雙向邊,容量為 INF
,費用為 k,然而要註意這道題並不是要求最大流,這道題要求的是可行流,這個只需要修改一下求增廣的過程就可以了,最後答案就是費用流的相反數。
#include <bits/stdc++.h> using namespace std; const int inf = 0x3FFFFFFF; const int maxn = 2222; struct node{ int st, en, flow, cost, next; node(){} node(int st, int en, int flow, int cost, int next):st(st),en(en),flow(flow),cost(cost),next(next){} }E[101000]; int num, p[maxn]; void init(){ memset(p, -1, sizeof(p)); num = 0; } void add(int st, int en, int flow, int cost){ E[num] = node(st, en, flow, cost, p[st]); p[st] = num++; E[num] = node(en, st, 0, -cost, p[en]); p[en] = num++; } int pre[maxn]; int dis[maxn]; bool fg[maxn]; bool spfa(int st, int en) { for(int i=0;i<=en;i++){ fg[i] = 0, dis[i] = inf, pre[i]=-1; } queue<int>q; q.push(st); fg[st]=1; dis[st]=0; while(!q.empty()){ int u = q.front(); q.pop(); fg[u]=0; for(int i=p[u];~i;i=E[i].next){ int v = E[i].en; if(E[i].flow&&dis[v]>dis[u]+E[i].cost){ dis[v] = dis[u]+E[i].cost; pre[v]=i; if(!fg[v]){ fg[v]=1; q.push(v); } } } } // if(dis[en] < inf) return 1; // return 0; return dis[en]<=0; } int solve(int st, int en){ int ans=0; while(spfa(st,en)){ int d = inf; for(int i=pre[en];i+1;i=pre[E[i].st]) d = min(d, E[i].flow); for(int i=pre[en];i+1;i=pre[E[i].st]){ E[i].flow -= d; E[i^1].flow += d; ans += d*E[i].cost; } } return ans; } int main() { int n,m; while (cin>>n>>m) { init(); int s=0,t=n+1,cost; for (int i=1; i<=n; i++) { int a,b,c,d; cin>>a>>b>>c>>d; add(s,i,b,a); add(i,t,d,-c); } while (m--) { int u,v,k; cin>>u>>v>>k; add(u,v,inf,k); add(v,u,inf,k); } int ans = -solve(s,t); printf("%d\n", ans); } return 0; }
HDU 6118 度度熊的交易計劃 最大費用可行流