Ultraviolet A 11380-Down went the Titanic
Question Link
Give a picture with a thin ice on it '. 'or' * ', thick ice' @ ', wooden block' # '. At the beginning, people are on' * '. Thin Ice will sink only once, and the number of thick ice is unlimited, if a person is rescued after going to the block, but the size of a block is only P, how many people can be rescued?
Idea: The maximum stream. Because there is a limit on the number of points, you can split the points and create an edge in every 4 and 4 directions. The source point and '*' are created, '#' and the edge size of the sink point are P, and then run the maximum stream.
Code:
#include <cstdio>#include <cstring>#include <queue>#include <algorithm>using namespace std;const int MAXNODE = 2005;const int MAXEDGE = 100005;typedef int Type;const Type INF = 0x3f3f3f3f;struct Edge {int u, v;Type cap, flow;Edge() {}Edge(int u, int v, Type cap, Type flow) {this->u = u;this->v = v;this->cap = cap;this->flow = flow;}};struct Dinic {int n, m, s, t;Edge edges[MAXEDGE];int first[MAXNODE];int next[MAXEDGE];bool vis[MAXNODE];Type d[MAXNODE];int cur[MAXNODE];vector<int> cut;void init(int n) {this->n = n;memset(first, -1, sizeof(first));m = 0;}void add_Edge(int u, int v, Type cap) {edges[m] = Edge(u, v, cap, 0);next[m] = first[u];first[u] = m++;edges[m] = Edge(v, u, 0, 0);next[m] = first[v];first[v] = m++;}bool bfs() {memset(vis, false, sizeof(vis));queue<int> Q;Q.push(s);d[s] = 0;vis[s] = true;while (!Q.empty()) {int u = Q.front(); Q.pop();for (int i = first[u]; i != -1; i = next[i]) {Edge& e = edges[i];if (!vis[e.v] && e.cap > e.flow) {vis[e.v] = true;d[e.v] = d[u] + 1;Q.push(e.v);}}}return vis[t];}Type dfs(int u, Type a) {if (u == t || a == 0) return a;Type flow = 0, f;for (int &i = cur[u]; i != -1; i = next[i]) {Edge& e = edges[i];if (d[u] + 1 == d[e.v] && (f = dfs(e.v, min(a, e.cap - e.flow))) > 0) {e.flow += f;edges[i^1].flow -= f;flow += f;a -= f;if (a == 0) break;}}return flow;}Type Maxflow(int s, int t) {this->s = s; this->t = t;Type flow = 0;while (bfs()) {for (int i = 0; i < n; i++)cur[i] = first[i];flow += dfs(s, INF);}return flow;}void MinCut() {cut.clear();for (int i = 0; i < m; i += 2) {if (vis[edges[i].u] && !vis[edges[i].v])cut.push_back(i);}}} gao;const int N = 35;const int d[4][2] = {1, 0, -1, 0, 0, 1, 0, -1};int x, y, p;char str[N];int main() {while (~scanf("%d%d%d", &x, &y, &p)) {int tot = x * y;gao.init(2 * tot + 2);for (int i = 0; i < x; i++) {scanf("%s", str);for (int j = 0; j < y; j++) {int u = i * y + j + 1;if (str[j] == '*' || str[j] == '.') {gao.add_Edge(u, u + tot, 1);if (str[j] == '*')gao.add_Edge(0, u, 1);}if (str[j] == '#') {gao.add_Edge(u, u + tot, INF);gao.add_Edge(u + tot, 2 * tot + 1, p);}if (str[j] == '@') gao.add_Edge(u, u + tot, INF);for (int k = 0; k < 4; k++) {int xx = i + d[k][0];int yy = j + d[k][1];if (xx < 0 || xx >= x || yy < 0 || yy >= y) continue;int v = xx * y + yy + 1;gao.add_Edge(u + tot, v, INF);}}}printf("%d\n", gao.Maxflow(0, 2 * tot + 1));}return 0;}
Ultraviolet A 11380-Down went the Titanic (Network Stream)