// 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);
int lca = ver[0];
for (int i = 1; i < k; i++) lca = __lca(lca, ver[i]);
for (int i = 0; i < k; i++) {
for (int j = i + 1; j < k; j++) {
if (isAncestor(ver[i], ver[j]))
ver[i] = ver[j];
else if (isAncestor(ver[j], ver[i]))
ver[j] = ver[i];
};
};
sort(ver, ver + k);
k = unique(ver, ver + k) - ver;
ll res = 0;
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;
};
Compilation message (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 time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |