hdu 6118 度度熊的交易计划(可行费用流)

题目链接:hdu 6118 度度熊的交易计划

题意:

中文,说的很清楚了。

题解:

对着输入建一些图,跑一下可行费用流就行了,即当费用为正的时候就不跑了,这样就先满足了费用最小。

 1 #include<bits/stdc++.h>
 2 #define F(i,a,b) for(int i=(a);i<=(b);++i)
 3 using namespace std;
 4 
 5 namespace MCMF
 6 {
 7     const int N=1e5+7,inf=1e9+7;
 8     int u[N],v[N],cost[N],cap[N],g[N],nxt[N],ed,a[N],n;
 9     int S,T,d[N],Q[N],sumcost,flow,inq[N],p[N],now=1;
10     void adg(int s,int t,int c,int co)
11     {
12         int &x=ed;
13         u[x]=s,v[x]=t,cap[x]=c,cost[x]=co,nxt[x]=g[s],g[s]=x,x++;
14         u[x]=t,v[x]=s,cap[x]=0,cost[x]=-co,nxt[x]=g[t],g[t]=x,x++;
15     }
16     void init(int _n)
17     {
18         S=_n+1,T=_n+2,n=T,ed=0;
19         for(int i=0;i<=n;i++)g[i]=-1;
20     }
21     bool spfa()
22     {
23         for(int i=0;i<=n;i++)d[i]=inf;
24         d[S]=0,inq[S]=now,p[S]=0,a[S]=inf;
25         int head=1,tail=1;Q[1]=S;
26         while(head<=tail)
27         {
28             int x=Q[head++];
29             inq[x]--;
30             if(x==T)continue;
31             for(int i=g[x];~i;i=nxt[i])
32             {
33                 if(cap[i]>0&&d[v[i]]>d[x]+cost[i])
34                 {
35                     d[v[i]]=d[x]+cost[i];
36                     p[v[i]]=i,a[v[i]]=min(a[x],cap[i]);
37                     if(inq[v[i]]<now)inq[v[i]]=now,Q[++tail]=v[i];
38                 }
39             }
40         }
41         if(d[T]==inf||d[T]>=0)return 0;
42         flow+=a[T],sumcost+=d[T]*a[T];
43         int x=T;
44         while(x!=S)cap[p[x]]-=a[T],cap[p[x]^1]+=a[T],x=u[p[x]];
45         return 1;
46     }
47     int mcmf()
48     {
49         flow=sumcost=0;
50         while(spfa())now++;
51         return sumcost;
52     }
53 }
54 
55 int n,m,a,b,c,d;
56 
57 int main()
58 {
59     while(~scanf("%d%d",&n,&m))
60     {
61         MCMF::init(2*n);
62         F(i,1,n)
63         {
64             scanf("%d%d%d%d",&a,&b,&c,&d);
65             MCMF::adg(MCMF::S,i,b,a);
66             MCMF::adg(i,MCMF::T,d,-c);
67         }
68         F(i,1,m)
69         {
70             scanf("%d%d%d",&a,&b,&c);
71             if(a==b)continue;
72             MCMF::adg(a,b,2000,c);
73             MCMF::adg(b,a,2000,c);
74         }
75         printf("%d
",-MCMF::mcmf());
76     }
77     return 0;
78 }
View Code
原文地址:https://www.cnblogs.com/bin-gege/p/7354248.html