CF1263F Economic Difficulties
我是网络流锰锌,这道题折磨了我很久。
我们发现这里面每条边可选可不选,并且都有一定的限制条件,于是我们的思路可以往网络流方面靠拢。那么题目要求最大化,我们发现用最大流并不好做,于是考虑转化为最小割。其中要割的边就是我们要选的边数。
根据套路很自然的我们先考虑将
然后最难的地方是如何处理电机的两端。我们需要建出两个中至少选择一个的关系。我们可以将图改造一下,把第二棵树代表边的每个点向
这样子建图的边数仅仅是
代码:
#include <bits/stdc++.h>
#define rep(i, l, r) for (int i = l; i <= r; ++ i)
#define rrp(i, l, r) for (int i = r; i >= l; -- i)
#define eb emplace_back
#define inf 1000000000
#define linf 10000000000000000
#define pii pair <int, int>
using namespace std;
const int N = 5e4 + 5;
inline int rd ()
{
int x = 0, f = 1;
char ch = getchar ();
while (! isdigit (ch)) { if (ch == '-') f = -1; ch = getchar (); }
while (isdigit (ch)) { x = (x << 1) + (x << 3) + ch - 48; ch = getchar (); }
return x * f;
}
int n, a, b, p[N], x[N], q[N], y[N], s, t;
namespace mf
{
int h[N], to[N], nxt[N], val[N], tot = 1;
int dep[N];
queue <int> q;
void init ()
{
rep (i, 0, t) h[i] = 0;
tot = 1;
}
void add (int u, int v, int w)
{
to[++ tot] = v;
val[tot] = w;
nxt[tot] = h[u];
h[u] = tot;
to[++ tot] = u;
val[tot] = 0;
nxt[tot] = h[v];
h[v] = tot;
}
int bfs ()
{
q.push (s);
rep (i, 0, t) dep[i] = 0;
dep[s] = 1;
while (! q.empty ())
{
int u = q.front ();
q.pop ();
for (int i = h[u]; i; i = nxt[i])
{
int v = to[i], w = val[i];
if (! w || dep[v]) continue;
dep[v] = dep[u] + 1;
q.push (v);
}
}
return dep[t];
}
int dfs (int u, int g)
{
if (u == t) return g;
int flow = 0;
for (int i = h[u]; i; i = nxt[i])
{
int v = to[i], w = val[i];
if (! w || dep[v] != dep[u] + 1) continue;
int tmp = dfs (v, min (g, w));
flow += tmp, val[i ^ 1] += tmp;
val[i] -= tmp, g -= tmp;
}
if (! flow) dep[u] = 0;
return flow;
}
int solve ()
{
int flow = 0;
while (bfs ()) flow += dfs (s, inf);
return flow;
}
}
signed main ()
{
n = rd ();
a = rd ();
rep (i, 2, a)
{
int j = rd ();
if (j == 1) continue;
mf::add (j, i, inf);
}
rep (i, 1, n) x[i] = rd ();
b = rd ();
rep (i, 2, b)
{
int j = rd ();
if (j == 1) continue;
mf::add (i + a, j + a, inf);
}
rep (i, 1, n)
{
y[i] = rd ();
mf::add (x[i], y[i] + a, inf);
}
t = a + b + 1;
rep (i, 2, a) mf::add (0, i, 1);
rep (i, 2, b) mf::add (a + i, t, 1);
printf ("%d\n", a - 1 + b - 1 - mf::solve ());
}
/*
1
6 2 6
1 2 1 3 2 2
*/
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?