poj2516

来源:互联网 发布:如何淘宝店铺装修 编辑:程序博客网 时间:2024/06/05 00:45

最小费用最大流初探。过程极为简单:把边作为边权,然后找超级源点和超级汇点之间的最短路,如果有最短路,则对它增广。

http://blog.csdn.net/lin375691011/article/details/18923267

这是lin的博客,讲得(网络流的概念)比较详细。这个题的细节都在代码中了,就不再叙述了。

#include <iostream>#include <algorithm>#include <queue>using namespace std;#define M 105#define inf 1 << 30int capacity_need[M][M], capacity_have[M][M], construction_cost[M][M][M], n, m, k;int capacity[M][M];int flow[M][M];int weight[M][M];int shortestdistances[M];int pre_node[M];bool visited[M];/** *  insearch for shortest path from SuperSource[0], to SuperSink[n+m+1]; * *  @return whether there are shortest paths */bool spfa() {for (int i = 0; i <= n + m + 1; i++) {shortestdistances[i] = inf;pre_node[i] = -1;visited[i] = false;}shortestdistances[0] = 0;visited[0] = true;queue <int> q;q.push(0);while (!q.empty()) {int t = q.front();q.pop();visited[t] = false;for (int i = 1; i <= n + m + 1; i++) {if (capacity[t][i] > flow[t][i] && shortestdistances[i] > shortestdistances[t] + weight[t][i]) {shortestdistances[i] = shortestdistances[t] + weight[t][i];pre_node[i] = t;if (!visited[i]) {q.push(i);visited[i] = true;}}}}if (pre_node[n + m + 1] == -1) {return false;}return true;}/** *  get maxflow */void getMaxflow() { //if there is the shortest path, find the key edge that controls the flow, then change the flowwhile (spfa()) {int maxflow = inf;int p = n + m + 1;while (pre_node[p] != -1) { //findmaxflow = min(maxflow, capacity[pre_node[p]][p] - flow[pre_node[p]][p]); // from p'pre to p, the real flow equals to the capacity - flow_nowp = pre_node[p];}p = n + m + 1;while (pre_node[p] != -1) { //changeflow[pre_node[p]][p] += maxflow;flow[p][pre_node[p]] = -flow[pre_node[p]][p];p = pre_node[p];}}}int main() {int i, j, d, ans;while (cin >> n >> m >> k, n || m || k) {ans = 0;bool flag = false;for (i = 1; i <= n; i++) {for (j = 1; j <= k; j++) {cin >> capacity_need[i][j];}}for (i = 1; i <= m; i++) {for (j = 1; j <= k; j++) {cin >> capacity_have[i][j];}}for (i = 1; i <= k; i++) {for (j = 1; j <= n; j++) {for (d = 1; d <= m; d++) {cin >> construction_cost[i][d][j];}}}for (i = 1; i <= k; i++) {memset(capacity, 0, sizeof(capacity));memset(flow, 0, sizeof(flow));memset(weight, 0, sizeof(weight));for (j = 1; j <= m; j++) {capacity[0][j] = capacity_have[j][i]; //SuperSource's capacity should be the capacity current have(dust)}for (j = 1; j <= n; j++) {capacity[m + j][m + n + 1] = capacity_need[j][i]; //SuperSink's capacity should be the capacity current need(store)}for (j = 1; j <= m; j++) {for (d = 1; d <= n; d++) {capacity[j][d + m] = capacity_have[j][i]; //Dust to store should be the dust's capacity}}for (j = 1; j <= m; j++) {for (d = 1; d <= n; d++) {weight[j][d + m] = construction_cost[i][j][d];weight[d + m][j] = -construction_cost[i][j][d]; // MINUS FOR REMAINING FLOW NOW}}getMaxflow();for (j = 1; j <= n; j++) {if (capacity[j + m][n + m + 1] != flow[j + m][n + m + 1]) { // support != requirementflag = true;break;}}if (flag) {break;}for (j = 1; j <= m; j++) {for (d = 1; d <= n; d++) {ans += flow[j][d + m] * weight[j][d + m]; //CLEARLY RIGHT}}}if (flag) {cout << -1 << endl;}else {cout << ans << endl;}}}



0 0
原创粉丝点击