#include "bits/stdc++.h"
#define ll long long
#define ff first
#define ss second
#define edgew tuple<int, int, int>
#define edge pair<int,int>
using namespace std;
struct connectivity{
vector<int> ata;
vector<int> sz;
int n;
connectivity(int _n){
n = _n;
ata.resize(n+1);
sz.resize(n+1);
}
void init(){
for (int i = 1; i <= n; i++)
ata[i] = i, sz[i] = 1;
}
int tap(int x){
if (ata[x] == x)
return x;
return ata[x] = tap(ata[x]);
}
bool merge(int x, int y){
if ((x=tap(x)) == (y=tap(y)))
return 0;
if (sz[x] < sz[y])
swap(x, y);
ata[y] = x;
sz[x] += sz[y];
return 1;
}
bool is_connected(int x, int y){
return tap(x) == tap(y);
}
vector<int> get_components(){
vector<int> components;
for (int i = 1; i <= n; i++)
if (ata[i] == i)
components.push_back(i);
return components;
}
};
const int N = 1e5+5;
const int K = 20;
const int INF = 1e9;
edge blue_edges[K];
ll a[N];
vector<int> adj[N];
void add_edge(int u, int v){
adj[u].push_back(v);
adj[v].push_back(u);
}
ll sub[N];
int par[N], lvl[N], l[N];
void dfs(int nd, int pr){
par[nd] = pr;
sub[nd] = a[nd];
for (auto to: adj[nd])
if (to != pr){
lvl[to] = lvl[nd]+1;
dfs(to, nd);
sub[nd] += sub[to];
}
}
void upd(int u, int v, int w){
while (u != v){
if (lvl[u] > lvl[v])
swap(u, v);
l[v] = min(l[v], w);
v = par[v];
}
}
int n, m, k, root = 1;
vector<edgew> simplify(vector<edgew> edges){
assert(edges.size() <= n-1);
connectivity dsu(n);
dsu.init();
for (int i = 0; i < k; i++){
auto [u, v] = blue_edges[i];
dsu.merge(u, v);
}
vector<bool> essential(edges.size(), 0);
for (int i = 0; i < edges.size(); i++){
auto [w, u, v] = edges[i];
essential[i] = dsu.merge(u, v);
}
dsu.init();
for (int i = 0; i < edges.size(); i++){
auto [w, u, v] = edges[i];
if (essential[i])
dsu.merge(u, v);
}
vector<int> id(n+1);
vector<int> roots = dsu.get_components();
int np = 0;
for (int i = 0; i < roots.size(); i++)
id[roots[i]] = ++np;
vector<edgew> nedges;
for (int i = 0; i < edges.size(); i++){
auto [w, u, v] = edges[i];
if (!essential[i])
nedges.push_back({w, id[dsu.tap(u)], id[dsu.tap(v)]});
}
for (int i = 0; i < k; i++){
auto &[u, v] = blue_edges[i];
u = id[dsu.tap(u)];
v = id[dsu.tap(v)];
}
vector<ll> na(np+1);
for (int i = 1; i <= n; i++)
na[id[dsu.tap(i)]] += a[i];
n = np;
for (int i = 1; i <= n; i++)
a[i] = na[i];
root = id[dsu.tap(root)];
assert(nedges.size() <= k);
return nedges;
}
int main(){
// freopen("file.in", "r", stdin);
scanf("%d%d%d", &n, &m, &k);
vector<edgew> black_edges(m);
for (int i = 0; i < m; i++){
int u, v, w;
scanf("%d%d%d", &u, &v, &w);
black_edges[i] = {w, u, v};
}
sort(black_edges.begin(), black_edges.end());
connectivity dsu(n);
dsu.init();
// black edges
vector<edgew> selected;
for (int i = 0; i < m; i++){
auto [w, u, v] = black_edges[i];
if (dsu.merge(u, v))
selected.push_back(black_edges[i]);
}
for (int i = 0; i < k; i++){
int u, v;
scanf("%d%d", &u, &v);
blue_edges[i] = {u, v};
}
for (int i = 1; i <= n; i++)
scanf("%lld", a+i);
selected = simplify(selected);
assert(n <= k+1);
ll ans = 0;
connectivity ndsu(n);
for (int mask = 0; mask < (1<<k); mask++){
ndsu.init();
for (int i = 1; i <= n; i++)
adj[i].clear(), l[i] = INF;
bool valid = true;
for (int i = 0; i < k; i++)
if (mask>>i&1){
auto [u, v] = blue_edges[i];
add_edge(u, v);
if (!ndsu.merge(u, v))
valid = false;
}
if (!valid)
continue;
vector<bool> state(selected.size(), 0);
for (int i = 0; i < selected.size(); i++){
auto [w, u, v] = selected[i];
state[i] = ndsu.merge(u, v);
if (state[i])
add_edge(u, v);
}
dfs(root, -1);
for (int i = 0; i < selected.size(); i++){
auto [w, u, v] = selected[i];
if (!state[i])
upd(u, v, w);
}
ll value = 0;
for (int i = 0; i < k; i++)
if (mask>>i&1){
auto [u, v] = blue_edges[i];
add_edge(u, v);
if (lvl[u] > lvl[v])
swap(u, v);
value += l[v] * sub[v];
}
ans = max(ans, value);
}
printf("%lld\n", ans);
}
컴파일 시 표준 에러 (stderr) 메시지
toll.cpp: In function 'int main()':
toll.cpp:133:14: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
133 | scanf("%d%d%d", &n, &m, &k);
| ~~~~~^~~~~~~~~~~~~~~~~~~~~~
toll.cpp:137:22: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
137 | scanf("%d%d%d", &u, &v, &w);
| ~~~~~^~~~~~~~~~~~~~~~~~~~~~
toll.cpp:152:22: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
152 | scanf("%d%d", &u, &v);
| ~~~~~^~~~~~~~~~~~~~~~
toll.cpp:156:22: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
156 | scanf("%lld", a+i);
| ~~~~~^~~~~~~~~~~~~
# | 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... |