QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#402173 | #1076. Flooding Fields | stasio6# | AC ✓ | 479ms | 158900kb | C++14 | 3.6kb | 2024-04-30 04:41:40 | 2024-04-30 04:41:41 |
Judging History
answer
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define int ll
#define rep(i,a,b) for(int i = a; i < (b); i++)
#define all(x) begin(x), end(x)
#define sz(x) (int)(x).size()
#define PB push_back
#define FS first
#define SD second
typedef pair<int, int> pii;
typedef vector<int> vi;
template<class X, class Y> X cmx(X &a, Y b) { a = max<X>(a, b); }
#define ary(k) array<int, k>
void out(int k) {
cout << k%2 << " ";
k /= 2;
cout << k/9 << " " << k/3%3 << " " << k%3 << " ";
}
struct Dinic {
struct Edge {
int to, rev;
ll c, oc;
ll flow() { return max(oc - c, 0LL);}
};
vi lvl, ptr, q;
vector<vector<Edge>> adj;
Dinic(int n) : lvl(n), ptr(n), q(n), adj(n) {}
void addEdge(int a, int b, ll c, ll rcap = 0) {
// out(a); out(b); cout << "\n";
adj[a].push_back({b, sz(adj[b]), c, c});
adj[b].push_back({a, sz(adj[a])-1, rcap, rcap});
}
ll dfs(int v, int t, ll f) {
if (v == t || !f) return f;
for (int &i = ptr[v]; i < sz(adj[v]); i++) {
Edge &e = adj[v][i];
if (lvl[e.to] == lvl[v] + 1)
if (ll p = dfs(e.to, t, min(f, e.c))) {
e.c -= p, adj[e.to][e.rev].c += p;
return p;
}
}
return 0;
}
ll calc(int s, int t) {
ll flow = 0; q[0] = s;
rep(L,0,31) do {
lvl=ptr=vi(sz(q));
int qi = 0, qe = lvl[s] = 1;
while (qi < qe && !lvl[t]) {
int v = q[qi++];
for (Edge e : adj[v])
if (!lvl[e.to] && e.c >> (30 - L))
q[qe++] = e.to, lvl[e.to] = lvl[v] + 1;
}
while (ll p = dfs(s, t, LLONG_MAX)) flow += p;
} while (lvl[t]);
return flow;
}
bool leftOfMinCut(int a) {return lvl[a] != 0;}
};
int height[102][102];
int flood[25];
int dirx[5] = {0, 0, 1, 0, -1};
int diry[5] = {0, 1, 0, -1, 0};
signed main() {
cin.tie(0)->sync_with_stdio(0); cin.exceptions(cin.failbit);
while (true) {
int n, m, h;
cin >> n >> m >> h;
if (n == 0 && m == 0 && h == 0) {
break;
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
cin >> height[i][j];
}
}
int source = n*n*(h+1)*2, sink = n*n*(h+1)*2+1;
Dinic dinic(sink+1);
for (int i = 0; i < m; i++) {
int x, y;
cin >> x >> y;
dinic.addEdge(source, (x*n+y)*2, 1);
}
flood[0] = -1;
for (int k = 1; k <= h; k++) {
cin >> flood[k];
}
for (int k = 0; k <= h; k++) {
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
int cur = (k*n*n+n*i+j)*2;
if (flood[k] < height[i][j])
dinic.addEdge(cur, cur+1, 1);
if (k == h) {
dinic.addEdge(cur+1, sink, 1);
continue;
}
for (int hh = 0; hh < 5; hh++) {
int ni = i + dirx[hh], nj = j + diry[hh];
if (ni < 0 || ni >= n || nj < 0 || nj >= n)
continue;
int nast = ((k+1)*n*n+n*ni+nj)*2;
dinic.addEdge(cur+1, nast, 1);
}
}
}
}
cout << dinic.calc(source, sink) << "\n";
}
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 479ms
memory: 158900kb
input:
3 1 3 2 1 2 3 1 3 2 4 2 1 1 0 2 1 2 4 2 0 1 1 2 0 0 0 1 1 1 1 0 1 0 50 50 24 5 20 21 3 2 9 22 15 19 22 18 14 19 14 15 4 22 22 7 12 7 2 2 0 25 0 7 6 4 3 2 17 1 12 7 12 1 19 12 3 23 5 5 10 22 15 17 3 13 4 10 21 7 12 10 22 23 18 17 5 17 18 2 14 12 13 13 19 19 18 8 11 3 0 24 0 6 1 9 12 14 13 20 22 5 13 ...
output:
1 1 1 2 2 2 0 92 99 71
result:
ok 10 lines