Submission #2388379


Source Code Expand

//「何らかの全域木からS--Tパス上の辺を取り除いたもの」を考えればよく、実は「MST - (S--Tパス上の最大コストの辺)」が答えになりそう。
#include <iostream>
#include <vector>
#include <algorithm>
#define int long long
using namespace std;

struct UF {
	int par[4000];
	UF() { for (int i = 0; i < 4000; i++) par[i] = i; }
	int root(int x) { if (par[x] == x) return x; return par[x] = root(par[x]); }
	void unit(int x, int y) { x = root(x); y = root(y); par[x] = y; }
	bool isSame(int x, int y) { return root(x) == root(y); }
};

struct Edge {
	int from, to, cost;
	Edge(int from, int to, int cost) { this->from = from; this->to = to; this->cost = cost; }
	Edge() {}
	bool operator<(const Edge &r) const { return cost < r.cost; }
};
typedef vector<Edge> Edges;
typedef vector<Edges> Graph;

int n, m, q;
Edges edges;
UF uf;
Graph mst;
int parents[20][4000];
int depth[4000];
int maxScores[20][4000];

void dfs(int p, int v, int ecost, int dep) {
	parents[0][v] = p;
	depth[v] = dep;
	maxScores[0][v] = ecost;
	
	for (int i = 0; i < mst[v].size(); i++) {
		int nv = mst[v][i].to;
		if (nv == p) continue;
		dfs(v, nv, mst[v][i].cost, dep + 1);
	}
}

int maxPath(int u, int v) {
	int ret = 0, i;
	
	if (depth[u] > depth[v]) swap(u, v);
	if (depth[v] > depth[u]) {
		int d = depth[v] - depth[u];
		for (i = 0; i < 20; i++) {
			if ((d >> i) & 1) {
				ret = max(ret, maxScores[i][v]);
				v = parents[i][v];
			}
		}
	}
	if (u == v) { return ret; }
	if (parents[0][u] == parents[0][v]) {
		int res = max(maxScores[0][u], maxScores[0][v]);
		return max(ret, res);
	}
	
	for (i = 19; i > 0; i--) {
		if (parents[i][u] != parents[i][v]) break;
	}
	int res1 = maxPath(parents[i][u], parents[i][v]);
	int res2 = max(maxScores[i][u], maxScores[i][v]);
	int res = max(res1, res2);
	return max(ret, res);
}

signed main() {
	int i, j;
	
	cin >> n >> m;
	for (i = 0; i < m; i++) {
		int a, b, c;
		cin >> a >> b >> c;
		a--; b--;
		edges.push_back(Edge(a, b, c));
	}
	sort(edges.begin(), edges.end());
	
	int mstCost = 0;
	mst.resize(n);
	for (i = 0; i < edges.size(); i++) {
		int u = edges[i].from;
		int v = edges[i].to;
		
		if (!uf.isSame(u, v)) {
			uf.unit(u, v);
			mstCost += edges[i].cost;
			mst[u].push_back(Edge(u, v, edges[i].cost));
			mst[v].push_back(Edge(v, u, edges[i].cost));
		}
	}
	
	dfs(0, 0, 0, 0);
	for (i = 1; i < 20; i++) {
		for (j = 0; j < n; j++) {
			parents[i][j] = parents[i - 1][parents[i - 1][j]];
			maxScores[i][j] = max(maxScores[i - 1][j], maxScores[i - 1][parents[i - 1][j]]);
		}
	}
	
	cin >> q;
	for (i = 0; i < q; i++) {
		int s, t;
		cin >> s >> t; s--; t--;
		if (n <= 2) { cout << 0 << endl; continue; }
		int res = maxPath(s, t);
		cout << mstCost - res << endl;
	}
	return 0;
}

Submission Info

Submission Time
Task A - Graph
User startcpp
Language C++14 (GCC 5.4.1)
Score 700
Code Size 2876 Byte
Status AC
Exec Time 629 ms
Memory 14700 KB

Judge Result

Set Name Sample subtask1 subtask2 All
Score / Max Score 0 / 0 200 / 200 300 / 300 200 / 200
Status
AC × 2
AC × 12
AC × 21
AC × 31
Set Name Test Cases
Sample sample_1.txt, sample_2.txt
subtask1 sample_2.txt, subtask_1_1.txt, subtask_1_10.txt, subtask_1_11.txt, subtask_1_2.txt, subtask_1_3.txt, subtask_1_4.txt, subtask_1_5.txt, subtask_1_6.txt, subtask_1_7.txt, subtask_1_8.txt, subtask_1_9.txt
subtask2 sample_1.txt, sample_2.txt, subtask_1_1.txt, subtask_1_10.txt, subtask_1_11.txt, subtask_1_2.txt, subtask_1_3.txt, subtask_1_4.txt, subtask_1_5.txt, subtask_1_6.txt, subtask_1_7.txt, subtask_1_8.txt, subtask_1_9.txt, subtask_2_1.txt, subtask_2_2.txt, subtask_2_3.txt, subtask_2_4.txt, subtask_2_5.txt, subtask_2_6.txt, subtask_2_7.txt, subtask_2_8.txt
All sample_1.txt, sample_2.txt, sample_1.txt, sample_2.txt, subtask_1_1.txt, subtask_1_10.txt, subtask_1_11.txt, subtask_1_2.txt, subtask_1_3.txt, subtask_1_4.txt, subtask_1_5.txt, subtask_1_6.txt, subtask_1_7.txt, subtask_1_8.txt, subtask_1_9.txt, subtask_2_1.txt, subtask_2_2.txt, subtask_2_3.txt, subtask_2_4.txt, subtask_2_5.txt, subtask_2_6.txt, subtask_2_7.txt, subtask_2_8.txt, subtask_3_1.txt, subtask_3_2.txt, subtask_3_3.txt, subtask_3_4.txt, subtask_3_5.txt, subtask_3_6.txt, subtask_3_7.txt, subtask_3_8.txt
Case Name Status Exec Time Memory
sample_1.txt AC 1 ms 384 KB
sample_2.txt AC 1 ms 384 KB
subtask_1_1.txt AC 2 ms 512 KB
subtask_1_10.txt AC 192 ms 7020 KB
subtask_1_11.txt AC 1 ms 384 KB
subtask_1_2.txt AC 41 ms 2804 KB
subtask_1_3.txt AC 381 ms 12780 KB
subtask_1_4.txt AC 6 ms 2048 KB
subtask_1_5.txt AC 7 ms 1984 KB
subtask_1_6.txt AC 97 ms 4208 KB
subtask_1_7.txt AC 385 ms 14444 KB
subtask_1_8.txt AC 6 ms 2048 KB
subtask_1_9.txt AC 12 ms 2172 KB
subtask_2_1.txt AC 399 ms 13164 KB
subtask_2_2.txt AC 389 ms 14700 KB
subtask_2_3.txt AC 389 ms 13676 KB
subtask_2_4.txt AC 391 ms 14444 KB
subtask_2_5.txt AC 13 ms 2048 KB
subtask_2_6.txt AC 29 ms 2424 KB
subtask_2_7.txt AC 104 ms 4336 KB
subtask_2_8.txt AC 390 ms 14444 KB
subtask_3_1.txt AC 613 ms 14056 KB
subtask_3_2.txt AC 612 ms 14440 KB
subtask_3_3.txt AC 230 ms 3328 KB
subtask_3_4.txt AC 242 ms 3452 KB
subtask_3_5.txt AC 421 ms 8812 KB
subtask_3_6.txt AC 519 ms 14060 KB
subtask_3_7.txt AC 629 ms 14316 KB
subtask_3_8.txt AC 616 ms 14316 KB