Visits (USACO Silver 2022 Open)
Functional Graph。每个环上要去掉一个数(肯定去掉最小的数),其它的都可以包含在结果里。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int n;
int p[100005];
int v[100005];
bool cycle[100005];
bool nocycle[100005];
typedef long long ll;
ll total;
int main() {
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
scanf("%d %d", &p[i], &v[i]);
total += v[i];
}
for (int i = 1; i <= n; i++) {
if (cycle[i] || nocycle[i]) continue;
// Floyd to find cycle
bool iscycle = true;
int a = i;
int b = p[a];
while (a != b) {
if (cycle[b] || nocycle[b]) {
iscycle = false;
break;
}
a = p[a];
b = p[p[b]];
}
if (iscycle) {
// Mark all cycle nodes and find smallest
int minv = v[a];
b = p[a];
cycle[a] = true;
while (b != a) {
cycle[b] = true;
minv = min(minv, v[b]);
b = p[b];
}
// subtract smallest v from total
total -= minv;
}
// Mark the path as nocycle
a = i;
while (!cycle[a] && !nocycle[a]) {
nocycle[a] = true;
a = p[a];
}
}
printf("%lld", total);
return 0;
}