You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
166 lines
4.9 KiB
C++
166 lines
4.9 KiB
C++
#define _CRT_SECURE_NO_WARNINGS
|
|
#define _SILENCE_CXX17_C_HEADER_DEPRECATION_WARNING
|
|
#include <bits/stdc++.h>
|
|
using namespace std;
|
|
#define CRP(t, x) const t &x
|
|
#define OPL(t, x) bool operator<(CRP(t, x)) const
|
|
#define FIL(x, v) memset(x, v, sizeof(x))
|
|
#define CLR(x) FIL(x, 0)
|
|
#define NE1(x) FIL(x, -1)
|
|
#define INF(x) FIL(x, 0x3f)
|
|
typedef long long ll, i64;
|
|
const int inf = 0x3f3f3f3f;
|
|
const int N = 5e3 + 50, M = N * N;
|
|
void printTime()
|
|
{
|
|
static auto base = chrono::high_resolution_clock::now().time_since_epoch().count();
|
|
auto ne = chrono::high_resolution_clock::now().time_since_epoch().count();
|
|
printf("%lf\n", (ne - base) / 1e9);
|
|
base = ne;
|
|
}
|
|
void printTime2()
|
|
{
|
|
return;
|
|
static auto base = chrono::high_resolution_clock::now().time_since_epoch().count();
|
|
static int cnt = 0;
|
|
auto ne = chrono::high_resolution_clock::now().time_since_epoch().count();
|
|
if (cnt++ % 10000 == 0) printf("10000 loops using %lf\n", (ne - base) / 1e9), base = ne;
|
|
}
|
|
struct Edge
|
|
{
|
|
int nxt, to, len, cap;
|
|
} E[M];
|
|
int adj[N], dis[N], H[N], ecnt, idx, T, pre[N];
|
|
struct edge
|
|
{
|
|
int to, capacity, cost, rev;
|
|
edge() {}
|
|
edge(int to, int _capacity, int _cost, int _rev) : to(to), capacity(_capacity), cost(_cost), rev(_rev) {}
|
|
};
|
|
vector<edge> G[N + 5];
|
|
//µ÷ÓÃǰ³õʼ»¯
|
|
void Init(int n)
|
|
{
|
|
for (int i = 0; i <= n; ++i) G[i].clear();
|
|
}
|
|
//¼Ó±ß
|
|
void Add_Edge(int from, int to, int cap, int cost)
|
|
{
|
|
G[from].push_back(edge(to, cap, cost, G[to].size()));
|
|
G[to].push_back(edge(from, 0, -cost, G[from].size() - 1));
|
|
}
|
|
inline void _int_addEdge(int f, int t, int l, int c)
|
|
{
|
|
E[ecnt] = {adj[f], t, l, c};
|
|
adj[f] = ecnt++;
|
|
}
|
|
inline void addEdge(int f, int t, int l, int c)
|
|
{
|
|
Add_Edge(f, t, c, l);
|
|
_int_addEdge(f, t, l, c);
|
|
_int_addEdge(t, f, -l, 0);
|
|
}
|
|
int countEdges(int u)
|
|
{
|
|
int cnt = 0;
|
|
for (int e = adj[u]; ~e; e = E[e].nxt) cnt++;
|
|
return cnt;
|
|
}
|
|
pair<int, int> MCMF(int S)
|
|
{
|
|
fill(H, H + 1 + T, 0);
|
|
struct heap_node
|
|
{
|
|
int u, d;
|
|
OPL(heap_node, rhs) { return d > rhs.d || (d == rhs.d && u > rhs.u); }
|
|
};
|
|
int flow = 0, cost = 0;
|
|
for (;;)
|
|
{
|
|
priority_queue<heap_node> pq;
|
|
fill(dis, dis + 1 + T, inf);
|
|
int cnt = 0, cnt2 = 0;
|
|
printTime();
|
|
for (pq.push({S, dis[S] = 0}); !pq.empty();)
|
|
{
|
|
int u = pq.top().u, d = pq.top().d;
|
|
pq.pop();
|
|
if (dis[u] < d) continue;
|
|
for (int kk = 1; kk; kk--)
|
|
{
|
|
for (int e = adj[u]; ~e; e = E[e].nxt)
|
|
cnt2 += E[e].len;
|
|
for (int i = G[u].size() - 1; i >= 0; --i)
|
|
cnt2 -= G[u][i].cost;
|
|
}
|
|
for (int e = adj[u]; ~e; e = E[e].nxt)
|
|
if (E[e].cap && dis[E[e].to] > d + E[e].len + H[u] - H[E[e].to])
|
|
{
|
|
printTime2();
|
|
cnt++;
|
|
pq.push({E[e].to, dis[E[e].to] = d + E[e].len + H[u] - H[E[e].to]});
|
|
pre[E[e].to] = e;
|
|
}
|
|
}
|
|
printf("- %d %d\n", cnt, cnt2);
|
|
printTime();
|
|
putchar('\n');
|
|
if (dis[T] == inf) break;
|
|
for (int i = 0; i <= T; i++) H[i] += dis[i];
|
|
int f = inf;
|
|
for (int u = T; u != S; u = E[pre[u] ^ 1].to)
|
|
f = min(f, E[pre[u]].cap);
|
|
for (int u = T; u != S; u = E[pre[u] ^ 1].to)
|
|
E[pre[u]].cap -= f, E[pre[u] ^ 1].cap += f;
|
|
flow += f, cost += f * H[T];
|
|
}
|
|
return make_pair(flow, cost);
|
|
}
|
|
int a[N];
|
|
inline void readint(int &x)
|
|
{
|
|
int ch = x = 0;
|
|
while (!isdigit(ch)) ch = getchar();
|
|
for (; isdigit(ch); ch = getchar()) x = x * 10 + ch - '0';
|
|
}
|
|
int main()
|
|
{
|
|
#ifdef _MSC_VER
|
|
freopen(R"(E:\UserData\Desktop\1009\multi.in)", "r", stdin);
|
|
#endif // _MSC_VER
|
|
int T, n, k;
|
|
readint(T);
|
|
while (T--)
|
|
{
|
|
NE1(adj), ecnt = 0;
|
|
ll ans = 0;
|
|
readint(n), readint(k), ::T = (n + 1) << 1 | 1;
|
|
Init(::T);
|
|
int s2 = (n + 1) << 1;
|
|
addEdge(0, s2, 0, k);
|
|
for (int i = 1; i <= n; i++)
|
|
{
|
|
readint(a[i]);
|
|
addEdge(s2, i, 0, 1);
|
|
addEdge(i << 1, i << 1 | 1, -a[i], 1);
|
|
addEdge(i << 1 | 1, ::T, 0, 1);
|
|
}
|
|
for (int i = 1; i <= n; i++)
|
|
for (int j = 1; j < i; j++)
|
|
if (a[j] <= a[i])
|
|
addEdge(j << 1 | 1, i << 1, 0, 1);
|
|
printTime();
|
|
int cnt = 0;
|
|
for (int k = 0; k < 100000000; k++)
|
|
for (int i = 0; i <= T; i++)
|
|
for (int e = adj[i]; ~e; e = E[e].nxt)
|
|
cnt += E[e].to;
|
|
printTime2();
|
|
printTime();
|
|
printf("[%d]\n", cnt);
|
|
puts("---");
|
|
printf("%d\n", -MCMF(0).second);
|
|
printTime();
|
|
}
|
|
return 0;
|
|
} |