QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#323194 | #7737. Extending Distance | complexor | WA | 1ms | 10040kb | C++23 | 5.3kb | 2024-02-08 20:20:56 | 2024-02-08 20:20:56 |
Judging History
answer
#include <bits/stdc++.h>
#define clr(f, n) memset(f, 0, (n) << 2)
#define cpy(f, g, n) memcpy(f, g, (n) << 2)
typedef long long LL;
typedef unsigned long long ULL;
typedef __int128 LLL;
typedef std::pair<int, int> pii;
typedef std::pair<LL, LL> pll;
#define MP std::make_pair
#define fi first
#define se second
int read()
{
int s = 0, f = 1;
char c = getchar();
while (!(c >= '0' && c <= '9'))
f ^= (c == '-'), c = getchar();
while (c >= '0' && c <= '9')
s = s * 10 + (c ^ 48), c = getchar();
return f ? s : -s;
}
const int MAXN = 505, MAXM = 2005;
const LL INF = 0x3f3f3f3f3f3f3f3fll;
int n, m, r[MAXN][MAXN], d[MAXN][MAXN], K, N;
int S, T;
LL dist[MAXN][MAXN];
int nxt[MAXM], to[MAXM], cst[MAXM], pre[MAXN], tot = -1;
int L[MAXN][MAXN], R[MAXN][MAXN], U[MAXN][MAXN], D[MAXN][MAXN];
int head[MAXN], cur[MAXN];
LL cap[MAXN];
void add_edge(int u, int v, LL w, int c)
{ to[++tot] = v, nxt[tot] = head[u], cap[tot] = w, cst[tot] = c, head[u] = tot; }
void add_net(int u, int v, LL w, int c)
{ add_edge(u, v, w, c), add_edge(v, u, 0, -c); }
LL dis[MAXN];
bool vis[MAXN];
pll dfs(int x, LL lim)
{
if (vis[x]) return MP(0, 0);
if (x == T) return MP(lim, 0);
vis[x] = true;
LL F = 0, C = 0;
for (int &e = cur[x]; ~e; e = nxt[e])
if (cap[e] && dis[to[e]] == dis[x] + cst[e])
{
pll tmp = dfs(to[e], std::min(lim, cap[e]));
F += tmp.fi, C += tmp.fi * cst[e] + tmp.se;
lim -= tmp.fi, cap[e] -= tmp.fi, cap[e ^ 1] += tmp.fi;
if (!lim) return MP(F, C);
}
return MP(F, C);
}
bool modify()
{
if (vis[T]) return true;
LL mn = INF;
for (int i = 1; i <= N; i++) if (vis[i])
for (int e = head[i]; ~e; e = nxt[e])
if (cap[e] && !vis[to[e]])
mn = std::min(dis[i] + cst[e] - dis[to[e]], mn);
if (mn >= INF) return false;
for (int i = 1; i <= N; i++)
if (vis[i]) dis[i] -= mn;
return true;
}
pll MCMF()
{
LL F = 0, C = 0;
memset(dis + 1, 0, N << 3);
dis[S] = -INF;
do
{
memset(vis + 1, false, N);
memcpy(cur + 1, head + 1, N << 2);
pll res = dfs(S, INF);
F += res.fi, C += res.se;
} while (modify()) ;
return MP(F, C);
}
struct Node
{
int x, y; LL d;
Node(){}
Node(int _x, int _y, LL _d)
: x(_x), y(_y), d(_d) {}
friend bool operator<(Node a, Node b)
{ return a.d > b.d; }
} ;
void Dijkstra()
{
static bool vis[MAXN][MAXN];
static std::priority_queue<Node> q;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
dist[i][j] = INF, vis[i][j] = false;
for (int i = 1; i <= n; i++)
q.emplace(i, 1, dist[i][1] = 0);
while (!q.empty())
{
Node x = q.top(); q.pop();
if (vis[x.x][x.y]) continue;
vis[x.x][x.y] = true;
if (x.x < n && dist[x.x + 1][x.y] > x.d + d[x.x][x.y])
q.emplace(x.x + 1, x.y, dist[x.x + 1][x.y] = x.d + d[x.x][x.y]);
if (x.x > 1 && dist[x.x - 1][x.y] > x.d + d[x.x - 1][x.y])
q.emplace(x.x - 1, x.y, dist[x.x - 1][x.y] = x.d + d[x.x - 1][x.y]);
if (x.y < m && dist[x.x][x.y + 1] > x.d + r[x.x][x.y])
q.emplace(x.x, x.y + 1, dist[x.x][x.y + 1] = x.d + r[x.x][x.y]);
if (x.y > 1 && dist[x.x][x.y - 1] > x.d + r[x.x][x.y - 1])
q.emplace(x.x, x.y - 1, dist[x.x][x.y - 1] = x.d + r[x.x][x.y - 1]);
}
}
int main()
{
for (int Tcnt = read(); Tcnt--; )
{
n = read(), m = read(), K = read();
for (int i = 1; i <= n; i++)
for (int j = 1; j < m; j++)
r[i][j] = read();
for (int i = 1; i < n; i++)
for (int j = 1; j <= m; j++)
d[i][j] = read();
Dijkstra();
LL lim = INF;
for (int i = 1; i <= n; i++)
lim = std::min(dist[i][m], lim);
lim += K;
// printf("%d\n", lim);
N = (n - 1) * (m - 1);
S = ++N, T = ++N;
int s = ++N, t = ++N;
memset(head + 1, -1, N << 2), tot = -1;
add_net(S, s, lim, 0), add_net(t, T, lim, 0);
#define id(i, j) (((i) - 1) * (m - 1) + (j))
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
L[i][j] = R[i][j] = U[i][j] = D[i][j] = -1;
for (int i = 1; i < m; i++)
{
add_net(s, id(1, i), r[1][i], 0);
add_net(s, id(1, i), INF, 1), R[1][i] = tot;
}
for (int i = 1; i < m; i++)
{
add_net(id(n - 1, i), t, r[n][i], 0);
add_net(id(n - 1, i), t, INF, 1), R[n][i] = tot;
}
for (int i = 1; i < n - 1; i++)
for (int j = 1; j < m; j++)
{
add_net(id(i, j), id(i + 1, j), r[i + 1][j], 0);
add_net(id(i, j), id(i + 1, j), INF, 1), R[i + 1][j] = tot;
add_net(id(i + 1, j), id(i, j), r[i + 1][j], 0);
add_net(id(i + 1, j), id(i, j), INF, 1), L[i + 1][j + 1] = tot;
}
for (int i = 1; i < n; i++)
for (int j = 1; j < m - 1; j++)
{
add_net(id(i, j), id(i, j + 1), d[i][j + 1], 0);
add_net(id(i, j), id(i, j + 1), INF, 1), D[i][j + 1] = tot;
add_net(id(i, j + 1), id(i, j), d[i][j + 1], 0);
add_net(id(i, j + 1), id(i, j), INF, 1), U[i + 1][j + 1] = tot;
}
printf("%lld\n", MCMF().se);
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
{
if (~L[i][j] && cap[L[i][j]]) r[i][j - 1] += cap[L[i][j]];
if (~R[i][j] && cap[R[i][j]]) r[i][j] += cap[R[i][j]];
if (~D[i][j] && cap[D[i][j]]) d[i][j] += cap[D[i][j]];
if (~U[i][j] && cap[U[i][j]]) d[i - 1][j - 1] += cap[U[i][j]];
}
for (int i = 1; i <= n; i++)
for (int j = 1; j < m; j++)
printf("%d%c", r[i][j], " \n"[j + 1 == m]);
for (int i = 1; i < n; i++)
for (int j = 1; j <= m; j++)
printf("%d%c", d[i][j], " \n"[j == m]);
}
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 0
Wrong Answer
time: 1ms
memory: 10040kb
input:
2 3 4 6 2 1 15 7 1 9 13 3 2 3 6 1 2 5 2 15 3 3 3 3 1 1 2 2 3 3 1 1 1 2 2 2
output:
9 2 1 15 8 1 9 13 3 5 3 11 1 2 5 2 15 3 4 1 4 2 3 3 3 1 1 1 2 2 2
result:
wrong answer The length of shortest path shoult extend exactly K. (test case 1)