[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 度度熊的交易计划(网络流-最小费用最大流)