답안 #401764

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
401764 2021-05-10T19:28:17 Z Jorge213 통행료 (APIO13_toll) C++17
78 / 100
2500 ms 9548 KB
#include <bits/stdc++.h>
using namespace std;

struct Edge {
	int u, v;
	long long w;
	bool operator<(const Edge &e) const {
		return w < e.w;
	}
};

struct DSU {
	vector<int> dsu;

	DSU(int n): dsu(n) {
		for (int i = 1; i < n; i++)
			dsu[i] = i;
	}

	void clear(int n) {
		for (int i = 1; i < n; i++) {
			dsu[i] = i;
		}
	}

	int root(int idx) {
		while (idx != dsu[idx]) {
			dsu[idx] = dsu[dsu[idx]];
			idx = dsu[idx];
		}
		return idx;
	}

	bool join(int a, int b) {
		if (root(a) == root(b))
			return false;
		dsu[root(a)] = root(b);
		return true;
	}
};

struct Tree {
	vector<vector<pair<int, long long>>> adjList;
	vector<long long> we, cnt;
	vector<int> d, par;

	Tree(int sz, vector<long long> &a): 
		adjList(sz), we(sz), d(sz, 0), par(sz), cnt(a) {};

	void addEdge(int u, int v, long long w) {
		adjList[u].push_back({v, w});
		adjList[v].push_back({u, w});
	}

	void dfs(int v, int p) {
		par[v] = p;
		d[v] = d[p] + 1;
		for (auto [u, w] : adjList[v]) {
			if (u == p) continue;
			dfs(u, v);
			we[u] = w;
			cnt[v] += cnt[u];
		}
	}
};

int main() {
	ios_base::sync_with_stdio(0);
	cin.tie(0);

	int n, m, k;
	cin >> n >> m >> k; 

	vector<Edge> edges, nedges;
	vector<long long> a(n + 1);

	int ai, bi;
	long long ci;
	for (int i = 0; i < m; i++) {
		cin >> ai >> bi >> ci;
		edges.push_back({ai, bi, ci});
	}

	sort(edges.begin(), edges.end());

	int xi, yi;
	for (int i = 0; i < k; i++) {
		cin >> xi >> yi;
		nedges.push_back({xi, yi, 0});
	}

	for (int i = 1; i <= n; i++) {
		cin >> a[i];
	}

	DSU dsu(n + 1), ndsu(n + 1);
	for (auto [u, v, w] : nedges) {
		ndsu.join(u, v);
	}

	for (auto [u, v, w] : edges) {
		if (ndsu.join(u, v))
			dsu.join(u, v);
	}

	int sz = 0;
	vector<int> comp(n + 1, 0);
	vector<long long> p = {0};

	for (int i = 1; i <= n; i++) {
		int v = dsu.root(i);
		if (!comp[v]) {
			comp[v] = ++sz;
			p.push_back(0);
		}
		comp[i] = comp[v];
		p[comp[i]] += a[i];
	}

	for (auto &[u, v, w] : nedges) {
		u = comp[u], v = comp[v];
	}

	DSU dsu2(sz + 1);
	vector<Edge> mn;
	for (auto [u, v, w] : edges) {
		if (dsu2.join(comp[u], comp[v])) {
			mn.push_back({comp[u], comp[v], w});
		}
	}

	long long ans = 0;
	for (int bm = 1; bm < (1 << k); bm++) {
		Tree g(sz + 1, p);
		DSU st(sz + 1);
		int ecnt = 0;

		bool valid = true;
		for (int i = 0; valid && i < k; i++) {
			if (!(bm & (1 << i))) continue;
			auto [u, v, w] = nedges[i];
			if ((valid = st.join(u, v))) {
				g.addEdge(u, v, LLONG_MAX);
				ecnt++;
			}
		}

		if (!valid) 
			continue;

		vector<Edge> unused;
		for (auto [u, v, w] : mn) {
			if (st.join(u, v)) {
				g.addEdge(u, v, 0);
				ecnt++;
			}
			else {
				unused.push_back({u, v, w});
			}
		}

		g.dfs(1, -1);
		for (auto [u, v, w] : unused) {
			if (g.d[u] < g.d[v])
				swap(u, v);

			while (g.d[u] > g.d[v]) {
				g.we[u] = min(g.we[u], w);
				u = g.par[u];
			}
		
			while (u != v) {
				g.we[u] = min(g.we[u], w);
				g.we[v] = min(g.we[v], w);
				u = g.par[u], v = g.par[v];
			}
		}

		long long can = 0;
		for (int v = 1; v <= sz; v++) {
			can += g.we[v] * g.cnt[v];
		}

		ans = max(ans, can);
	}

	cout << ans << '\n';

	return 0;
}

Compilation message

toll.cpp: In constructor 'Tree::Tree(int, std::vector<long long int>&)':
toll.cpp:45:17: warning: 'Tree::par' will be initialized after [-Wreorder]
   45 |  vector<int> d, par;
      |                 ^~~
toll.cpp:44:24: warning:   'std::vector<long long int> Tree::cnt' [-Wreorder]
   44 |  vector<long long> we, cnt;
      |                        ^~~
toll.cpp:47:2: warning:   when initialized here [-Wreorder]
   47 |  Tree(int sz, vector<long long> &a):
      |  ^~~~
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 204 KB Output is correct
2 Correct 1 ms 204 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 204 KB Output is correct
2 Correct 1 ms 204 KB Output is correct
3 Correct 2 ms 204 KB Output is correct
4 Correct 2 ms 204 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 204 KB Output is correct
2 Correct 1 ms 204 KB Output is correct
3 Correct 2 ms 204 KB Output is correct
4 Correct 2 ms 204 KB Output is correct
5 Correct 4 ms 460 KB Output is correct
6 Correct 4 ms 460 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 204 KB Output is correct
2 Correct 1 ms 204 KB Output is correct
3 Correct 2 ms 204 KB Output is correct
4 Correct 2 ms 204 KB Output is correct
5 Correct 4 ms 460 KB Output is correct
6 Correct 4 ms 460 KB Output is correct
7 Correct 241 ms 9408 KB Output is correct
8 Correct 243 ms 9548 KB Output is correct
9 Correct 239 ms 9424 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 204 KB Output is correct
2 Correct 1 ms 204 KB Output is correct
3 Correct 2 ms 204 KB Output is correct
4 Correct 2 ms 204 KB Output is correct
5 Correct 4 ms 460 KB Output is correct
6 Correct 4 ms 460 KB Output is correct
7 Correct 241 ms 9408 KB Output is correct
8 Correct 243 ms 9548 KB Output is correct
9 Correct 239 ms 9424 KB Output is correct
10 Execution timed out 2577 ms 9404 KB Time limit exceeded
11 Halted 0 ms 0 KB -