Visits (USACO Silver 2022 Open)

Visits (USACO Silver 2022 Open)

Functional Graph。每个环上要去掉一个数(肯定去掉最小的数),其它的都可以包含在结果里。

O(n)\mathcal{O}(n)

#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;
}