※ 글쓴이는 취미로 코딩을 익혀보는 사람이라 정확하지 않은 내용을 담고 있을 수 있다 ※

 

이번에 볼 문제는 백준 25050번 문제인 최고의 간선이다.
문제는 아래 링크를 확인하자.

https://www.acmicpc.net/problem/25050 

 

25050번: 최고의 간선

첫 번째 줄에는 두 개의 정수 $N$과 $M$이 공백으로 구분되어 주어집니다. $(2 \le N \le 2 \times 10^3, 1 \le M \le min(N\times (N-1),\ 5 \times 10^3))$ 다음 $M$개의 줄에는 $i$ 번째 간선의 시작 정점 $u_i$와 도착 정

www.acmicpc.net

이 문제는 "한 노드에서 다른 모든 노드까지의 최단경로"를 나타내는 트리를 구하고, 그 트리 위에서 DP를 이용해 각 에지의 사용횟수를 계산하는 것을 각 노드마다 반복하는 것으로 해결할 수 있다.

 

주어진 문제의 제약조건에서 주어지는 그래프의 총 에지 개수가 5000개 이하라는 조건을 확인하자.

 

dijkstra 알고리즘의 시간복잡도는 O(ElgV)이므로, 각 노드를 출발점으로 각각 하여 dijkstra 알고리즘을 한번씩 적용해보는 시간복잡도는 O(VElgV)가 된다. 이는 이 문제 제약조건 상에서 적당히 큰 V에 대해 Floyd-Warshall 알고리즘의 O(V^3)보다 나은 시간복잡도이며, 문제 해결에 충분한 시간복잡도이다.

 

아래는 제출한 소스코드이다.

#include <iostream>
#include <vector>
#include <queue>
using namespace std;
typedef long long ll;

int N, M;
vector<pair<int, int>> G[2001]; // {target, weight}

int edgeidx[2001][2001], edgeweight[2001][2001];

ll dist[2001];
vector<int> GG[2001];
void dijkstra(int s) {
	priority_queue<pair<ll, pair<int,int>>> pq; // {-d, {par, cur}}
	pq.push(make_pair(0, make_pair(0, s)));

	while (!pq.empty()) {
		ll d = -pq.top().first; int par = pq.top().second.first, cur = pq.top().second.second;
		pq.pop();
		if (dist[cur] < d) continue;

		GG[par].emplace_back(cur);

		for (auto& p : G[cur]) {
			int target = p.first; ll disttmp = d + p.second;
			if (disttmp < dist[target]) {
				dist[target] = disttmp;
				pq.push(make_pair(-disttmp, make_pair(cur, target)));
			}
		}
	}
}

int ans[5001];

int dfs(int cur) {
	int ret = 1;
	for (auto& x : GG[cur]) {
		int tmp = dfs(x);
		ans[edgeidx[cur][x]] += tmp;
		ret += tmp;
	}
	return ret;
}

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

	cin >> N >> M;
	for (int m = 1; m <= M; m++) {
		int x, y, w; cin >> x >> y >> w;
		if (edgeweight[x][y] == 0 || w < edgeweight[x][y]) {
			edgeweight[x][y] = w;
			edgeidx[x][y] = m;
			G[x].emplace_back(make_pair(y, w));
		}
	}

	for (int i = 1; i <= N; i++) {
		for (int i = 1; i <= N; i++) dist[i] = 1000000000000000007LL, GG[i].clear();
		dist[i] = 0;
		dijkstra(i);
		dfs(i);
	}

	int mx = -1;
	vector<int> vec;
	for (int m = 1; m <= M; m++) {
		if (ans[m] > mx) {
			mx = ans[m];
			vec.clear();
			vec.emplace_back(m);
		}
		else if (ans[m] == mx) vec.emplace_back(m);
	}

	cout << vec.size() << '\n';
	for (auto& x : vec) cout << x << ' ';
}
728x90

'BOJ' 카테고리의 다른 글

[BOJ 14410 // C++] Pareto  (0) 2022.10.08
[BOJ 14413 // C++] Poklon  (1) 2022.10.07
[BOJ 25049 // C++] 뮤직 플레이리스트  (0) 2022.10.05
[BOJ 25048 // C++] 랜선 연결  (1) 2022.10.04
[BOJ 25045 // C++] 비즈마켓  (0) 2022.10.03

+ Recent posts