Pre
神一样的\(MST\)
Solution
考虑计算出(或者直接得出)\(sum[i]\)和\(sum[i-1]\)来得出其情况。
转化为得到每一个前缀和(奇或者偶)的值。
对于一个询问\(i\to j\),我们可以由\(sum[i-1]\)得到\(sum[j]\)
于是不用计算其中的另外一个前缀和。
所以连边。
所以\(MST\)
Code
#include<bits/stdc++.h>
#define xx first
#define yy second
#define ll long long
#define mod 1000000007
using namespace std;
const int N = 2000 + 5;
struct Edge{
int u, v, l;
Edge (int a = 0, int b = 0, int c = 0) {
u = a, v = b, l = c;
}
}info[N * N];
int n, cnt, tmp;
int fa[N];
int Find (int u) {
return fa[u] == u ? u : fa[u] = Find (fa[u]);
}
bool cmp(Edge m, Edge n) {
return m.l < n.l;
}
int main () {
scanf ("%d", &n);
for (int i = 1; i <= n; ++i) {
fa[i] = i;
}
for (int i = 1; i <= n; ++i) {
for (int j = i; j <= n; ++j) {
scanf ("%d", &tmp);
cnt++;
info[cnt] = Edge (i - 1, j, tmp);
}
}
sort (info + 1, info + cnt + 1, cmp);
ll ans = 0;
int now = 0;
for (int i = 1; i <= cnt; ++i) {
int fx = Find (info[i].u), fy = Find (info[i].v);
if (fx != fy) {
ans += 1LL * info[i].l;
fa[fx] = fy;
now++;
if (now == n) {
break;
}
}
}
printf ("%lld\n", ans);
return 0;
}
Conclusion
还有这种转换方法,\(MST\)竟如此神奇。
有点信息论的感觉。