[HDOJ6118] 度度熊的交易计划(最小费用可行流)

Posted tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[HDOJ6118] 度度熊的交易计划(最小费用可行流)相关的知识,希望对你有一定的参考价值。

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6118

这个建图炒鸡简单,中间的图去掉重边后丢进去就行。

建图的时候费用实际上是价值,所以正的费用就不用跑了,相当于求费用可行流。

  1 /*
  2 ━━━━━┒ギリギリ♂ eye!
  3 ┓┏┓┏┓┃キリキリ♂ mind!
  4 ┛┗┛┗┛┃\○/
  5 ┓┏┓┏┓┃ /
  6 ┛┗┛┗┛┃ノ)
  7 ┓┏┓┏┓┃
  8 ┛┗┛┗┛┃
  9 ┓┏┓┏┓┃
 10 ┛┗┛┗┛┃
 11 ┓┏┓┏┓┃
 12 ┛┗┛┗┛┃
 13 ┓┏┓┏┓┃
 14 ┃┃┃┃┃┃
 15 ┻┻┻┻┻┻
 16 */
 17 #include <bits/stdc++.h>
 18 using namespace std;
 19 #define fr first
 20 #define sc second
 21 #define cl clear
 22 #define BUG puts("here!!!")
 23 #define W(a) while(a--)
 24 #define pb(a) push_back(a)
 25 #define Rint(a) scanf("%d", &a)
 26 #define Rll(a) scanf("%I64d", &a)
 27 #define Rs(a) scanf("%s", a)
 28 #define Cin(a) cin >> a
 29 #define FRead() freopen("in", "r", stdin)
 30 #define FWrite() freopen("out", "w", stdout)
 31 #define Rep(i, len) for(int i = 0; i < (len); i++)
 32 #define For(i, a, len) for(int i = (a); i < (len); i++)
 33 #define Cls(a) memset((a), 0, sizeof(a))
 34 #define Clr(a, x) memset((a), (x), sizeof(a))
 35 #define Full(a) memset((a), 0x7f7f7f, sizeof(a))
 36 #define lrt rt << 1
 37 #define rrt rt << 1 | 1
 38 #define pi 3.14159265359
 39 #define RT return
 40 #define lowbit(x) x & (-x)
 41 #define onenum(x) __builtin_popcount(x)
 42 typedef long long LL;
 43 typedef long double LD;
 44 typedef unsigned long long ULL;
 45 typedef pair<int, int> pii;
 46 typedef pair<string, int> psi;
 47 typedef pair<LL, LL> pll;
 48 typedef map<string, int> msi;
 49 typedef vector<int> vi;
 50 typedef vector<LL> vl;
 51 typedef vector<vl> vvl;
 52 typedef vector<bool> vb;
 53 
 54 typedef struct Node {
 55     int u, v, next;
 56     LL c, w;
 57 }Node;
 58 
 59 const int maxn = 550;
 60 const int maxm = 1010;
 61 const int inf = 0x7f7f7f7f;
 62 const LL mod = 0x3f3f3f3fLL;
 63 int n, m;
 64 int a[maxn], b[maxn], c[maxn], d[maxn];
 65 int f[maxn][maxn];
 66 
 67 
 68 int tot, head[maxn];
 69 LL dist[maxn];
 70 LL cost, flow;
 71 Node e[1001000];
 72 int pre[maxn];
 73 bool visit[maxn];
 74 queue<int> Q;
 75 int S, T, N;
 76 
 77 void init() {
 78     S = T = N = 0;
 79     memset(head, -1, sizeof(head));
 80     tot = 0;
 81 }
 82 
 83 void adde(int u, int v, LL c, LL w) {
 84     e[tot].u = u; e[tot].v = v; e[tot].c = c; e[tot].w = w; e[tot].next = head[u]; head[u] = tot++;
 85     e[tot].u = v; e[tot].v = u; e[tot].c = 0; e[tot].w = -w; e[tot].next = head[v]; head[v] = tot++;
 86 }
 87 bool spfa(int s, int t, int n) {
 88     int i;
 89     for(i = 0; i <= n; i++) {
 90         dist[i] = inf;
 91         visit[i] = 0;
 92         pre[i] = -1;
 93     }
 94     while(!Q.empty()) Q.pop();
 95     Q.push(s);
 96     visit[s] = true;
 97     dist[s] = 0;
 98     pre[s] = -1;
 99     while(!Q.empty()) {
100         int u = Q.front();
101         visit[u] = false;
102         Q.pop();
103         for(int j = head[u]; j != -1; j = e[j].next) {
104             if(e[j].c > 0 && dist[u] + e[j].w < dist[e[j].v]) {
105                 dist[e[j].v] = dist[u] + e[j].w;
106                 pre[e[j].v] = j;
107                 if(!visit[e[j].v]) {
108                     Q.push(e[j].v);
109                     visit[e[j].v] = true;
110                 }
111             }
112         }
113     }
114     return dist[t] < 0;
115     // if(dist[t] == inf) return false;
116     // else return true;
117 }
118 LL ChangeFlow(int t) {
119     LL det = mod;
120     int u = t;
121     while(~pre[u]) {
122         u = pre[u];
123         det = min(det, e[u].c);
124         u = e[u].u;
125     }
126     u = t;
127     while(~pre[u]) {
128         u = pre[u];
129         e[u].c -= det;
130         e[u ^ 1].c += det;
131         u = e[u].u;
132     }
133     return det;
134 }
135 LL MinCostFlow(int s, int t, int n) {
136     LL mincost, maxflow;
137     mincost = maxflow = 0;
138     while(spfa(s, t, n)) {
139         LL det = ChangeFlow(t);
140         mincost += det * dist[t];
141         maxflow += det;
142     }
143     cost = mincost;
144     flow = maxflow;
145     return mincost;
146 }
147 
148 inline bool scan_d(int &num) {
149     char in;bool IsN=false;
150     in=getchar();
151     if(in==EOF) return false;
152     while(in!=-&&(in<0||in>9)) in=getchar();
153     if(in==-){ IsN=true;num=0;}
154     else num=in-0;
155     while(in=getchar(),in>=0&&in<=9){
156         num*=10,num+=in-0;
157     }
158     if(IsN) num=-num;
159     return true;
160 }
161 
162 signed main() {
163     // freopen("in", "r", stdin);
164     int u, v, w;
165     while(scan_d(n)) {
166         scan_d(m);
167         For(i, 1, n+1) {
168             For(j, 1, n+1) {
169                 f[i][j] = inf;
170             }
171         }
172         For(i, 1, n+1) {
173             scan_d(a[i]); scan_d(b[i]);
174             scan_d(c[i]); scan_d(d[i]);
175             f[i][i] = 0;
176         }
177         Rep(i, m) {
178             scan_d(u); scan_d(v); scan_d(w);
179             if(f[u][v] > w) {
180                 f[u][v] = f[v][u] = w;
181             }
182         }
183         init();
184         S = 0, T = n + 1, N = T + 1;
185         For(i, 1, n+1) {
186             adde(i, T, d[i], -c[i]);
187             adde(S, i, b[i], a[i]);
188         }
189         For(i, 1, n+1) {
190             For(j, 1, n+1) {
191                 if(i == j) continue;
192                 if(f[i][j] != inf) adde(i, j, inf, f[i][j]);
193             }
194         }
195         LL ret = -MinCostFlow(S, T, N);
196         printf("%d\n", (int)ret);
197     }
198     return 0;
199 }

 

以上是关于[HDOJ6118] 度度熊的交易计划(最小费用可行流)的主要内容,如果未能解决你的问题,请参考以下文章

(最小费用流)hdu 6118(2017百度之星初赛B 1005) 度度熊的交易计划

HDU 6118 度度熊的交易计划 (最小费用流)

HDU 6118 度度熊的交易计划(网络流-最小费用最大流)

HDU 6118 度度熊的交易计划 最大费用可行流

HDU 6118 2017百度之星初赛B 度度熊的交易计划(费用流)

2017"百度之星"程序设计大赛 - 初赛(B)度度熊的交易计划