제출 #1267989

#제출 시각아이디문제언어결과실행 시간메모리
1267989ducdevCities (BOI16_cities)C++17
0 / 100
90 ms17992 KiB
// Author: 4uckd3v - Nguyen Cao Duc
#include <bits/stdc++.h>
using namespace std;

#define all(x) (x).begin(), (x).end()

typedef long long ll;
typedef pair<int, int> ii;

const int MAX_N = 1e5;
const int MOD = 1e9 + 7;

struct DSU {
    vector<int> par, sz;
    int n;

    int findSet(int u) {
        return u == par[u] ? u : par[u] = findSet(par[u]);
    };

    bool unionSet(int u, int v) {
        u = findSet(u), v = findSet(v);

        if (u == v) return false;

        if (sz[u] < sz[v]) swap(u, v);
        sz[u] += sz[v];
        par[v] = u;

        return true;
    };

    DSU(int n) : n(n) {
        par.resize(n + 1), sz.resize(n + 1);
        for (int u = 1; u <= n; u++) {
            par[u] = u;
            sz[u] = 1;
        };
    };
};

struct Edge {
    int u, v, w;
    Edge() {};
    Edge(int u, int v, int w) : u(u), v(v), w(w) {};

    bool operator<(const Edge &other) const {
        return w < other.w;
    };
};

int n, m, k, timer, lg;
int ver[5], tin[MAX_N + 5], tout[MAX_N + 5];
int up[MAX_N + 5][18];
ll f[MAX_N + 5];
vector<Edge> edges;
vector<ii> adj[MAX_N + 5];

void dfs(int u, int par) {
    tin[u] = ++timer;
    up[u][0] = par;

    for (int i = 1; i <= lg; i++)
        up[u][i] = up[up[u][i - 1]][i - 1];

    for (ii e : adj[u]) {
        int v = e.first, w = e.second;
        if (v == par) continue;
        f[v] = f[u] + w;
        dfs(v, u);
    };

    tout[u] = ++timer;
};

bool isAncestor(int u, int v) {
    return tin[u] <= tin[v] && tout[u] >= tout[v];
};

int __lca(int u, int v) {
    if (isAncestor(u, v)) return u;
    if (isAncestor(v, u)) return v;

    for (int i = lg; i >= 0; i--)
        if (!isAncestor(up[u][i], v))
            u = up[u][i];

    return up[u][0];
};

int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    if (fopen("MAIN.INP", "r")) {
        freopen("MAIN.INP", "r", stdin);
        freopen("MAIN.OUT", "w", stdout);
    };

    cin >> n >> k >> m;
    for (int i = 0; i < k; i++) cin >> ver[i];

    edges.reserve(m);
    while (m--) {
        int u, v, w;
        cin >> u >> v >> w;
        edges.push_back(Edge(u, v, w));
    };

    sort(all(edges));

    int numCC = n;
    DSU DSU(n);
    for (const Edge &e : edges) {
        int u = e.u, v = e.v, w = e.w;
        if (DSU.unionSet(u, v)) {
            adj[u].push_back(ii(v, w));
            adj[v].push_back(ii(u, w));
            numCC--;
        };
        if (numCC == 1) break;
    };

    lg = ceil(log2(n));
    dfs(1, 1);

    ll res = 0;

    int lca = ver[0];
    for (int i = 1; i < k; i++) lca = __lca(lca, ver[i]);
    for (int mask = 1; mask < (1 << k); mask++) {
        vector<int> subset;

        for (int i = 0; i < k; i++) {
            if (mask >> i & 1) {
                subset.push_back(ver[i]);
            };
        };

        int curLca = -1;
        for (int u : subset) {
            if (curLca == -1)
                curLca = u;
            else
                curLca = __lca(curLca, u);
        };

        if (__builtin_popcount(mask) & 1)
            res += f[curLca] - f[lca];
        else
            res -= f[curLca] - f[lca];
    };

    cout << res;
};

컴파일 시 표준 에러 (stderr) 메시지

cities.cpp: In function 'int main()':
cities.cpp:95:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
   95 |         freopen("MAIN.INP", "r", stdin);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
cities.cpp:96:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
   96 |         freopen("MAIN.OUT", "w", stdout);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...