#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);
	ll ans = 0;
	//O(2^k*nlogn)
	for (int mask = 0; mask < (1<<k); mask++){
		dsu.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 (!dsu.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] = dsu.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... |