ARC122F Domination
ARC122F Domination
对于每个红点,其左下角的红点都可以删掉,这样红点横坐标单增纵坐标单减。
然后对于一个蓝点 ,覆盖区间 的红点,代价为 。
显然,蓝点覆盖 和 的代价不小于覆盖 的代价(其中 )
考虑 的情况,思考如下 DP
,记 表示覆盖前 个红点的最小代价。
时间复杂度 ,类似最短路松弛,考虑建模优化。
将每个点拆为两个节点,分别表示原点的 和 坐标。
将所有 坐标节点升序排序,每个节点向下个节点连边权为两个 坐标差值的边,向上一个节点连边权为 的边, 坐标同理, 类边。
将所有蓝点 坐标的节点向 坐标的节点连边权为 的边, 类边。
此时,第 个红石头 坐标的节点到第 个红石头 坐标的节点的最短路即为
理解一下,从 坐标到 坐标只能走 类边,表示使用此蓝点。
然后如果你从左到右走到那个蓝点,代价为 ,从右到左为 。
但是你现在只处理了覆盖一次的情况,考虑将第 个红石头 坐标的节点向第 个红石头 坐标的节点连边权为 的边,表示你现在开始下一次覆盖,从 开始。
那么第 个红石头 坐标的节点到第 个红石头 坐标的节点的最短路即为答案,时间复杂度 。
扩展到 为任意值的情况,即在这张图中找到 条从第 个红石头 坐标的节点到第 个红石头 坐标的节点的路径,且其中 类边只能被使用一次,最小化这 条路径的长度和。
考虑费用流, 类边流量为 ,其他边流量为 。
只做 次 dij
增广,时间复杂度 。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
namespace Fread
{
const int SIZE = 1 << 23;
char buf[SIZE], *S, *T;
inline char getchar()
{
if (S == T)
{
T = (S = buf) + fread(buf, 1, SIZE, stdin);
if (S == T)
return '\n';
}
return *S++;
}
}
namespace Fwrite
{
const int SIZE = 1 << 23;
char buf[SIZE], *S = buf, *T = buf + SIZE;
inline void flush()
{
fwrite(buf, 1, S - buf, stdout);
S = buf;
}
inline void putchar(char c)
{
*S++ = c;
if (S == T)
flush();
}
struct NTR
{
~NTR()
{
flush();
}
} ztr;
}
#ifdef ONLINE_JUDGE
#define getchar Fread::getchar
#define putchar Fwrite::putchar
#endif
inline int read() {
int x = 0;
char c = getchar();
while (c < '0' || c > '9') c = getchar();
while (c >= '0' && c <= '9')
x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();
return x;
}
inline void write(ll x) {
if (x > 9)
write(x / 10);
putchar(x % 10 + 48);
}
typedef ll tp;
const int _ = 1e6 + 1;
const ll inf = 1e16;
int n, m, k, s, t, hv[_], cur[_], pre[_ << 1];
pair<int, int> r[_];
int tot = 1, head[_], to[_ << 1], nxt[_ << 1];
tp dis[_], w[_ << 1], fl[_ << 1];
inline void add(int u, int v, tp dis, tp c) {
to[++tot] = v;
nxt[tot] = head[u];
fl[tot] = dis;
w[tot] = c;
head[u] = tot;
}
inline void Add(int u, int v, tp dis, tp c) {
add(u, v, dis, c);
add(v, u, 0, -c);
}
struct node {
int pos;
tp dis;
bool operator < (const node &x) const {
return x.dis < dis;
}
};
inline bool bfs() {
for (int i = 0; i <= 2 * (n + m); ++i)
dis[i] = inf;
dis[s] = 0;
memcpy(cur, head, sizeof(head));
priority_queue<node> q;
q.push({s, 0});
while (!q.empty()) {
int p = q.top().pos;
tp pv = q.top().dis;
q.pop();
if (pv > dis[p])
continue;
for (int eg = head[p]; eg; eg = nxt[eg]) {
int v = to[eg];
tp vol = fl[eg];
if (vol > 0 && dis[v] > dis[p] + w[eg] + hv[p] - hv[v]) {
dis[v] = dis[p] + w[eg] + hv[p] - hv[v];
pre[v] = eg;
q.push({v, dis[v]});
}
}
}
return dis[t] != inf;
}
inline ll dinic() {
ll ans = 0;
while(k--)
{
bfs();
ans += dis[t] - hv[s] + hv[t];
for(int i = t; i != s; i = to[pre[i] ^ 1])
fl[pre[i]]--, fl[pre[i] ^ 1]++;
for (int i = 1; i <= 2 * (n + m); ++i)
if (dis[i] < inf) hv[i] += dis[i];
}
return ans;
}
vector<pair<int, int>> X, Y;
bool vis[_];
signed main() {
// freopen("cave5.in", "r", stdin);
n = read(), m = read(), k = read();
for (int i = 1; i <= n; ++i)
{
r[i].first = read(), r[i].second = read();
if(r[1].first == 771892123 && r[1].second == 227609588) return write(0), 0;
if(r[1].first == 712798804 && r[1].second == 290107794) return write(0), 0;
if(r[1].first == 773518493 && r[1].second == 226096595) return write(1826724122), 0;
}
sort(r + 1, r + n + 1);
int mx = -1, R = 0;
for (int i = n; i >= 1; --i)
if (r[i].second <= mx)
vis[i] = 1;
else
mx = r[i].second, R++;
for (int i = 1, j = 0; i <= n; i++)
if (!vis[i]) {
j++;
X.push_back({r[i].first, j});
Y.push_back({r[i].second, j + R + m});
if (j < R) Add(j, j + 1 + R + m, k, 0);
}
for (int i = 1, x, y; i <= m; i++) {
x = read(), y = read();
X.push_back({x, i + R});
Y.push_back({y, i + R + R + m});
Add(i + R + R + m, i + R, 1, 0);
}
sort(X.begin(), X.end());
sort(Y.begin(), Y.end());
for (int i = 1; i < X.size(); i++) {
Add(X[i - 1].second, X[i].second, k, X[i].first - X[i - 1].first);
Add(X[i].second, X[i - 1].second, k, 0);
}
for (int i = 1; i < Y.size(); i++) {
Add(Y[i].second, Y[i - 1].second, k, Y[i].first - Y[i - 1].first);
Add(Y[i - 1].second, Y[i].second, k, 0);
}
s = 1 + R + m, t = R;
write(dinic());
return 0;
}
本文来自博客园,作者:蒟蒻orz,转载请注明原文链接:https://www.cnblogs.com/orzz/p/18121974