[codevs 1913] 数字梯形问题
题解:
代码:
总内存耗费: 364B
#include
#include
#include
#include
#include
using namespace std;const int maxn = 400 + 10;
const int INF = 1000000007;int n, m, s, t, delta;
int map[maxn][maxn], ID[maxn][maxn];struct Edge {int from, to, cap, flow, cost;
};vector edges;
vector G[maxn];void AddEdge(int from, int to, int cap, int cost) {edges.push_back((Edge){from, to, cap, 0, cost});edges.push_back((Edge){to, from, 0, 0, -cost});int sz = edges.size();G[from].push_back(sz-2);G[to].push_back(sz-1);
}bool inq[maxn];
int a[maxn], d[maxn], p[maxn];bool BellmanFord(int& flow, int& cost) {for(int i = s; i <= t; i++) d[i] = INF;memset(inq, 0, sizeof(inq));d[s] = 0; inq[s] = 1; p[s] = 0; a[s] = INF;queue Q;Q.push(s);while(!Q.empty()) {int x = Q.front(); Q.pop();inq[x] = 0;for(int i = 0; i < G[x].size(); i++) {Edge& e = edges[G[x][i]];if(e.cap > e.flow && d[e.to] > d[x] + e.cost) {d[e.to] = d[x] + e.cost;p[e.to] = G[x][i];a[e.to] = min(a[x], e.cap-e.flow);if(!inq[e.to]) {Q.push(e.to);inq[e.to] = 1;}}}}if(d[t] == INF) return 0;flow += a[t];cost += d[t] * a[t];int x = t;while(x != s) {edges[p[x]].flow += a[t];edges[p[x]^1].flow -= a[t];x = edges[p[x]].from;}return 1;
}void MincostMaxflow() {int flow = 0, cost = 0;while(BellmanFord(flow, cost));cout << -cost << endl;
}void init() {cin >> m >> n;for(int i = 1; i <= n; i++)for(int j = 1; j < m+i; j++) {ID[i][j] = ++t;cin >> map[i][j];}delta = t;t = t * 2 + 1;
}void init_1() {for(int x = 1; x <= n; x++)for(int y = 1; y < x+m; y++) {int& id = ID[x][y];AddEdge(id, id+delta, 1, -map[x][y]);if(x == 1) AddEdge(s, id, 1, 0);if(x == n) AddEdge(id+delta, t, 1, 0); //key1else {AddEdge(id+delta, ID[x+1][y], 1, 0);AddEdge(id+delta, ID[x+1][y+1], 1, 0);}}
}void init_2() {for(int x = 1; x <= delta; x++) for(int i = 0; i < G[x].size(); i++) //key 2if(edges[G[x][i]].to == x + delta) {edges[G[x][i]].cap = m;break;}for(int y = 1; y < n+m; y++) {int x = ID[n][y] + delta;for(int i = 0; i < G[x].size(); i++) if(edges[G[x][i]].to == t) edges[G[x][i]].cap = m; //key 4}for(int i = 0; i < edges.size(); i++) edges[i].flow = 0;
}void init_3() {for(int i = 0; i < edges.size(); i++) {Edge& e = edges[i];e.flow = 0;if(e.cap && e.from != s) e.cap = m; //key 3}
}void debug() {for(int i = 0; i < edges.size(); i++) {Edge& e = edges[i];if(e.cap) printf("%d %d %d %d
", e.from, e.to, e.cap, e.cost);}
}void regulation_1() {init_1();//debug();MincostMaxflow();
}void regulation_2() {init_2();//debug();MincostMaxflow();
}void regulation_3() {init_3();//debug();MincostMaxflow();
}int main() {init();regulation_1();regulation_2();regulation_3();return 0;
}