Notice
Recent Posts
Recent Comments
Link
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
Archives
Today
Total
관리 메뉴

승형님의 블로그

백준 2307번, 도로검문 본문

Problem Solving/백준

백준 2307번, 도로검문

승형 2022. 11. 25. 09:51

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

 

2307번: 도로검문

그림 1은 어떤 도시의 주요 지점과 그 지점들 간의 이동시간을 나타낸 그래프이다. 그래프의 노드는 주요 지점을 나타내고  두 지점을 연결한 도로(에지)에 표시된 수는 그 도로로 이동할 때 걸

www.acmicpc.net

요약

 

간선 하나를 제거하여 1번 정점에서 N번 정점으로 가는 최단경로를 최대로 만든다.


1. 도시의 주요 지점 N개와 도로 M개로 이루어진 가중치 무방향 그래프가 주어진다.

 

2. 우선, 지연시킬 수 있는 최대 시간은 (간선 제거 후 최단경로) - (간선 제거 전 최단경로)이므로, 다익스트라를 통해 간선 제거 전 최단경로를 구한다.

 

3. 간선을 하나 제거하여 최단경로를 변경시키기 위해서는 제거하는 간선이 최단경로에 포함되어야만 한다. 따라서 2번 과정에서 최단경로 역추적을 같이 진행한다.

https://int-p.tistory.com/13

 

다익스트라(Dijkstra) 알고리즘과 최단경로 역추적

다익스트라 알고리즘을 활용하여 최단경로를 구할 때, 최단경로의 길이 뿐만 아니라 정확한 경로를 역추적 해야하는 필요성을 느낄 때가 있다. 기본적인 다익스트라 알고리즘은 다음과 같은 과

int-p.tistory.com

 

4. DFS로 최단경로를 탐색하며 최단경로에 포함된 모든 간선을 candidate 배열에 넣어준다.

 

5. 브루트포스 기법을 사용하여 candidate 배열의 모든 간선을 하나씩 제거하며 답을 구할 수 있다.

#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> pii;
typedef pair<pair<int, int>, int> piii;
const int INF = 0x3f3f3f3f;

struct cmp {
	bool operator() (pii A, pii B) {
		return A.first > B.first;
	}
};

int N, M, org, ans;
vector <pii> graph[1001];
vector <int> path[1001];
vector <pii> candidate;
int dist[1001];
int mark[1001];
int blocked[1001][1001];

void Dijkstra(int start);
void MakeCandidate(int node);

int main(void) {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cin >> N >> M;
	for (int i = 0; i < M; i++) {
		int A, B, T;
		cin >> A >> B >> T;
		graph[A].push_back({ B,T });
		graph[B].push_back({ A,T });
	}
	Dijkstra(1);
	org = dist[N];
	MakeCandidate(N);
	for (int i = 0; i < candidate.size(); i++) {
		blocked[candidate[i].first][candidate[i].second] = 1;
		blocked[candidate[i].second][candidate[i].first] = 1;
		Dijkstra(1);
		ans = max(ans, dist[N]);
		blocked[candidate[i].first][candidate[i].second] = 0;
		blocked[candidate[i].second][candidate[i].first] = 0;
	}
	if (ans == INF) cout << -1;
	else cout << ans - org;
	return 0;
}

void Dijkstra(int start) {
	for (int i = 1; i <= N; i++) dist[i] = INF;
	priority_queue <pii, vector<pii>, cmp> pq;
	dist[start] = 0;
	pq.push({ 0,start });
	while (pq.size()) {
		int now = pq.top().second;
		int val = pq.top().first;
		pq.pop();
		if (dist[now] < val) continue;
		for (int i = 0; i < graph[now].size(); i++) {
			int next = graph[now][i].first;
			if (blocked[now][next] == 1) continue; // 검문중인 도로
			int new_val = val + graph[now][i].second;
			if (dist[next] > new_val) {
				dist[next] = new_val;
				path[next].clear();
				path[next].push_back(now);
				pq.push({ new_val, next });
			}
			if (dist[next] == new_val) path[next].push_back(now);
		}
	}
}

void MakeCandidate(int node) {
	if (mark[node] != 0) return;
	if (node == 1) return;
	mark[node] = 1;
	for (int i = 0; i < path[node].size(); i++) {
		candidate.push_back({ node, path[node][i] });
		MakeCandidate(path[node][i]);
	}
}

 

Comments