Submission #978598

# Submission time Handle Problem Language Result Execution time Memory
978598 2024-05-09T11:14:24 Z steveonalex Toll (APIO13_toll) C++17
100 / 100
1752 ms 36896 KB
#include <bits/stdc++.h>
 
using namespace std;
 
typedef long long ll;
typedef unsigned long long ull;
 
#define ALL(v) (v).begin(), (v).end()
#define MASK(i) (1LL << (i))
#define GETBIT(mask, i) (((mask) >> (i)) & 1)
 
// mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
mt19937_64 rng(1);
ll rngesus(ll l, ll r){return ((ull) rng()) % (r - l + 1) + l;}
 
ll max(ll a, ll b){return (a > b) ? a : b;}
ll min(ll a, ll b){return (a < b) ? a : b;}
 
ll LASTBIT(ll mask){return mask & (-mask);}
ll pop_cnt(ll mask){return __builtin_popcountll(mask);}
ll ctz(ll mask){return __builtin_ctzll(mask);}
ll clz(ll mask){return __builtin_clzll(mask);}
ll logOf(ll mask){return 63 - clz(mask);}
 
template <class T1, class T2>
    bool minimize(T1 &a, T2 b){
        if (a > b){a = b; return true;}
        return false;
    }
template <class T1, class T2>
    bool maximize(T1 &a, T2 b){
        if (a < b){a = b; return true;}
        return false;
    }
template <class T>
    void printArr(T a, string separator = " ", string finish = "\n", ostream& out = cout){
        for(auto i: a) out << i << separator;
        out << finish;
    }
template <class T>
    void remove_dup(vector<T> &a){
        sort(ALL(a));
        a.resize(unique(ALL(a)) - a.begin());
    }
 
#define int long long
struct DSU{
    int n;
    vector<int> parent, sz, mi;
 
    DSU(int _n){
        n = _n;
        parent.resize(n+1); sz.resize(n+1, 1);
        for(int i = 1; i<=n; ++i) parent[i] = i;
        mi = parent;
    }
 
    int find_set(int u){return (u == parent[u]) ? u : (parent[u] = find_set(parent[u]));}
    bool same_set(int u, int v){return find_set(u) == find_set(v);}
    bool join_set(int u, int v){
        u = find_set(u), v = find_set(v);
        if (u != v){
            if (sz[u] < sz[v]) {swap(u, v); mi[u] = mi[v];}
            parent[v] = u;
            sz[u] += sz[v];
            return true;
        }
        return false;
    }

    int get_parent(int u){return mi[find_set(u)];}
};
 
const int N = 1e5 + 69;
const int INF = 1e9 + 69;
 
int n, m, k;
vector<array<int, 3>> path, useful;
vector<pair<int, int>> money;
vector<pair<int, int>> graph[N];
ll goon[N];
 
namespace Nig{
    vector<pair<int, int>> graph[N];
    ll chode[N], toll[N];
    int parent[N], h[N];
    void reset(){
        for(int i = 1; i<=n; ++i){
            graph[i].clear();
        }
    }
 
    void dfs(int u, int p){
        chode[u] = goon[u];
        for(pair<int, int> v: graph[u]) if (v.first != p){
            h[v.first] = h[u] + 1;
            parent[v.first] = u;
            if (v.second == 1) toll[v.first] = INF;
            else toll[v.first] = 0;

            dfs(v.first, u);
            chode[u] += chode[v.first];
        }
    }
 
    void go(int root, DSU &mst){
        vector<array<int, 3>> outlier;
        for(array<int, 3> i: useful){
            int u = i[0], v = i[1];
            if (mst.join_set(u, v)){
                graph[u].push_back({v, 0});
                graph[v].push_back({u, 0});
            }
            else outlier.push_back(i);
        }
        dfs(root, root);

        DSU nigga(n);
        for(array<int, 3> i: outlier){
            int u = i[0], v = i[1], w = i[2];
            u = nigga.get_parent(u), v = nigga.get_parent(v);
            while(u != v){
                if (h[u] > h[v]){
                    minimize(toll[u], w);
                    nigga.join_set(parent[u], u);
                }
                else{
                    minimize(toll[v], w);
                    nigga.join_set(parent[v], v);
                }
                u = nigga.get_parent(u), v = nigga.get_parent(v);
            }
        }
    }
}
 
signed main(void){
    ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);

    clock_t start = clock();
 
    #define int long long
    cin >> n >> m >> k;
    path.resize(m);
    for(int i = 0; i<m; ++i){
        for(int j = 0;j < 3; ++j) cin >> path[i][j];
    }
    sort(ALL(path), [] (array<int, 3> x, array<int, 3> y){return x[2] < y[2];});
 
    DSU mst(n);
    for(int i = 0; i<m; ++i){
        int u = path[i][0], v = path[i][1], w = path[i][2];
        if (mst.join_set(u, v)){
            useful.push_back(path[i]);
            graph[u].push_back({v, w});
            graph[v].push_back({u, w});
        }
    }
    money.resize(k);
    for(int i = 0; i<k; ++i) cin >> money[i].first >> money[i].second;
 
    for(int i = 1; i<=n; ++i) cin >> goon[i];
 
    mst = DSU(n);
    vector<array<int, 3>> annoying, chill;
    for(pair<int, int> i: money) mst.join_set(i.first, i.second);
    for(array<int, 3> i: useful){
        if (mst.join_set(i[0], i[1])) {
            chill.push_back(i);
        }
        else annoying.push_back(i);
    }
 
    mst = DSU(n);
    for(array<int, 3> i: chill) {
        mst.join_set(i[0], i[1]);
    }
    vector<int> S;
    S.push_back(0);
    for(int i= 1; i<=n; ++i) if (i == mst.find_set(i)) S.push_back(i);
 
    for(pair<int, int> &i: money){
        i.first = lower_bound(ALL(S), mst.find_set(i.first)) - S.begin();
        i.second = lower_bound(ALL(S), mst.find_set(i.second)) - S.begin();
    }
    for(array<int, 3> &i: annoying){
        i[0] = lower_bound(ALL(S), mst.find_set(i[0])) - S.begin();
        i[1] = lower_bound(ALL(S), mst.find_set(i[1])) - S.begin();
    }
    useful = annoying;
 
    vector<ll> sum(S.size());
    for(int i= 1; i<=n; ++i){
        int idx = lower_bound(ALL(S), mst.find_set(i)) - S.begin();
        sum[idx] += goon[i];
    }
 
    memset(goon, 0, sizeof goon);
    for(int i= 1; i<S.size(); ++i) goon[i] = sum[i];
 
    n = S.size() - 1;
 
    // cout << n << "\n";
    // for(int i = 1; i<=n; ++i) cout << goon[i] << " "; cout << "\n\n";
    // for(pair<int, int> i: money) cout << i.first << " " << i.second << "\n";
    // for(array<int, 3> i: useful) printArr(i);
 
    int root = lower_bound(ALL(S), mst.find_set(1)) - S.begin();
 
    ll ans = 0;
    for(int mask = 1; mask < MASK(k); ++mask){
        DSU mst(n);
        bool check = true;
        for(int i = 0; i<k; ++i) if (GETBIT(mask, i)){
            check = check && mst.join_set(money[i].first, money[i].second);
        }
        if (check == false) continue;
 
        Nig::reset();
 
        for(int i= 0; i<k; ++i) if (GETBIT(mask, i)) {
            int u = money[i].first, v = money[i].second;
            Nig::graph[u].push_back({v, 1});
            Nig::graph[v].push_back({u, 1});
        }
 
        Nig::go(root, mst);
 
        ll cur = 0;
        for(int i = 1; i<=n; ++i) if (i != root){
            cur += Nig::toll[i] * Nig::chode[i];
        }
        maximize(ans, cur);
    }
    cout << ans << "\n";

    cerr << "Time elapsed: " << clock() - start << "ms\n";
 
    return 0;
}

Compilation message

toll.cpp: In function 'int main()':
toll.cpp:199:20: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  199 |     for(int i= 1; i<S.size(); ++i) goon[i] = sum[i];
      |                   ~^~~~~~~~~
# Verdict Execution time Memory Grader output
1 Correct 2 ms 8908 KB Output is correct
2 Correct 2 ms 8796 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 2 ms 8908 KB Output is correct
2 Correct 2 ms 8796 KB Output is correct
3 Correct 2 ms 8796 KB Output is correct
4 Correct 3 ms 8884 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 2 ms 8908 KB Output is correct
2 Correct 2 ms 8796 KB Output is correct
3 Correct 2 ms 8796 KB Output is correct
4 Correct 3 ms 8884 KB Output is correct
5 Correct 4 ms 9052 KB Output is correct
6 Correct 4 ms 9052 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 2 ms 8908 KB Output is correct
2 Correct 2 ms 8796 KB Output is correct
3 Correct 2 ms 8796 KB Output is correct
4 Correct 3 ms 8884 KB Output is correct
5 Correct 4 ms 9052 KB Output is correct
6 Correct 4 ms 9052 KB Output is correct
7 Correct 184 ms 36224 KB Output is correct
8 Correct 185 ms 35764 KB Output is correct
9 Correct 162 ms 36124 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 2 ms 8908 KB Output is correct
2 Correct 2 ms 8796 KB Output is correct
3 Correct 2 ms 8796 KB Output is correct
4 Correct 3 ms 8884 KB Output is correct
5 Correct 4 ms 9052 KB Output is correct
6 Correct 4 ms 9052 KB Output is correct
7 Correct 184 ms 36224 KB Output is correct
8 Correct 185 ms 35764 KB Output is correct
9 Correct 162 ms 36124 KB Output is correct
10 Correct 1338 ms 35656 KB Output is correct
11 Correct 1744 ms 36884 KB Output is correct
12 Correct 1752 ms 36896 KB Output is correct