[codevs 1917] 深海机器人问题
[codevs 1917] 深海机器人问题
题解:
看题建图。
“k个深海机器人从(x,y)位置坐标出发”、“r个深海机器人可选择(x,y)位置坐标作为目的地”,嗯~暗示已经很清楚了。
一开始没理解题目中关于地图大小的叙述,还要记得建立多重边(有点方格取数2的味道)。
代码:
总时间耗费: 5ms
总内存耗费: 364B
#include<cstdio> #include<iostream> #include<vector> #include<queue> #include<algorithm> using namespace std; const int maxn = 500 + 10; const int INF = 1e9 + 7; struct Edge { int from, to, cap, flow, cost; }; vector<Edge> edges; vector<int> 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 m = edges.size(); G[from].push_back(m-2); G[to].push_back(m-1); } int s, t; int ID[maxn][maxn]; int d[maxn*maxn], p[maxn*maxn], a[maxn*maxn]; bool inq[maxn]; bool BellmanFord(int& cost) { for(int i = s; i <= t; i++) d[i] = INF; memset(inq, 0, sizeof(inq)); d[s] = 0; inq[s] = 1; a[s] = INF; p[s] = 0; queue<int> 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; cost += a[t] * d[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 cost = 0; while(BellmanFord(cost)); cout << -cost << endl; } int main() { int A, B, m, n; cin >> A >> B >> m >> n; m++; n++; s = 0; t = m*n + 1; for(int x = 1, c = 1; x <= m; x++) for(int y = 1; y <= n; y++, c++) ID[x][y] = c; for(int x = 1; x <= m; x++) for(int y = 1; y < n; y++) { int& from = ID[x][y]; int& to = ID[x][y+1]; int cost; cin >> cost; AddEdge(from, to, 1, -cost); AddEdge(from, to, INF, 0); } for(int y = 1; y <= n; y++) for(int x = 1; x < m; x++) { int& from = ID[x][y]; int& to = ID[x+1][y]; int cost; cin >> cost; AddEdge(from, to, 1, -cost); AddEdge(from, to, INF, 0); } for(int i = 1; i <= A; i++) { int k, x, y; cin >> k >> x >> y; AddEdge(s, ID[x+1][y+1], k, 0); } for(int i = 1; i <= B; i++) { int r, x, y; cin >> r >> x >> y; AddEdge(ID[x+1][y+1], t, r, 0); } MincostMaxflow(); return 0; }