Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[cpp] 백준 13907. 세금 (Platinum IV) (민코딩 다익스트라의 탑 2번. 통행) #57

Merged
merged 2 commits into from
Sep 2, 2023

Conversation

minjae9610
Copy link
Member

🌁 Background

민코딩 다익스트라 과제

👩‍💻 Contents

[Platinum IV] 세금 - 13907

image
image

#include <algorithm>
#include <iostream>
#include <limits>
#include <queue>
#include <vector>

using namespace std;

struct Edge {
	int to;
	int cost;
	Edge(int to, int cost) : to(to), cost(cost) {}
};

struct Node {
	int id;
	int dist;
	int edge_count;
	Node(int id, int dist, int edge_count) : id(id), dist(dist), edge_count(edge_count) {}
};

vector<Edge> graph[1000];
int dist[1001][1001];

void dijkstra(int s, int e) {
	queue<Node> pq;
	pq.push(Node(s, 0, 0));
	dist[s][0] = 0;
	while (!pq.empty()) {
		Node node = pq.front();
		pq.pop();
		if (node.dist > dist[node.id][node.edge_count]) continue;
		for (Edge edge : graph[node.id]) {
			int next_dist = node.dist + edge.cost;
			if (next_dist < dist[edge.to][node.edge_count + 1]) {
				dist[edge.to][node.edge_count + 1] = next_dist;
				pq.push({ edge.to, next_dist, node.edge_count + 1 });
			}
		}
	}
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	cout.tie(nullptr);

	int n, m, k, a, b;
	cin >> n >> m >> k >> a >> b;
	for (int i = 1; i <= n; i++)
		for (int j = 0; j < n; j++)
			dist[i][j] = numeric_limits<int>::max();
	for (int i = 0; i < m; ++i)
	{
		int f, t, c;
		cin >> f >> t >> c;
		graph[f].push_back(Edge(t, c));
		graph[t].push_back(Edge(f, c));
	}

	dijkstra(a, b);

	vector<pair<int, int>> cand;
	int min_dist = dist[b][0];
	for (int i = 1; i < n; ++i) {
		if (dist[b][i] < min_dist) {
			min_dist = dist[b][i];
			cand.emplace_back(dist[b][i], i);
		}
	}
	sort(cand.begin(), cand.end());
	cout << cand[0].first << '\n';

	for (int i = 0; i < k; ++i) {
		int p;
		cin >> p;
		for (int j = 0; j < cand.size(); ++j)
			cand[j].first += p * cand[j].second;
		sort(cand.begin(), cand.end());
		vector<pair<int, int>> new_cand;
		new_cand.push_back(cand[0]);
		int min_edge_count = cand[0].second;
		for (int j = 1; j < cand.size(); ++j)
			if (cand[j].second < min_edge_count)
				new_cand.push_back(cand[j]);
		cand = new_cand;
		cout << cand[0].first << '\n';
	}

	return 0;
}

📱 Screenshot

image

📝 Review Note

민코딩에서 다익스트라를 중첩해서 작동시키는 방법으로 1차적으로 해결한 뒤, 백준에서 타임아웃을 마주쳤다.
이를 해결하기 위해 DP를 적용했고, 타임아웃은 해결했으나, 1초 이상의 시간이 소요되는 불편한 상황이 발생했다.
속도를 올릴 방법을 생각하던 중, 어쳐피 DP를 적용하기 때문에 우선순위 큐를 사용할 필요가 없다는 결론과, 결과에 그리디 알고리즘을 추가로 적용해 영원히 최소 경로가 될 수 없는 경우의 수를 제거해주며 최적화를 한 결과 소요 시간을 250ms까지 줄일 수 있었다.

@minjae9610 minjae9610 added #DP 백준 백준 문제 민코딩 민코딩 문제 #Dijkstra labels Aug 13, 2023
@minjae9610 minjae9610 requested a review from a team as a code owner August 13, 2023 13:49
@minjae9610 minjae9610 requested review from kgh2120 and Sumin-Kim-dev and removed request for a team August 13, 2023 13:49
@minjae9610 minjae9610 changed the title [cpp] 백준 13907. 세금 (Platinum IV) (민코딩 다익스트라의 탑 2번. 통행 [cpp] 백준 13907. 세금 (Platinum IV) (민코딩 다익스트라의 탑 2번. 통행) Aug 15, 2023
Copy link
Contributor

@Sumin-Kim-dev Sumin-Kim-dev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

제가 cpp를 잘 몰라서 질문이 두가지 있습니다

  1. emplace_back은 일반적인 push_back과 어떻게 다른건가요?
  2. pair를 정렬할 때 기준이 따로 명시되어있지 않은데, 이 경우에는 무엇을 기준으로 정렬되나요? 첫번째 원소 기준 오름차순이어야 논리상 맞아보이긴 하는데 맞나요?

seoul_21_minjaekim/BoJ/Platinum IV/boj13907/boj13907.cpp Outdated Show resolved Hide resolved
@minjae9610
Copy link
Member Author

제가 cpp를 잘 몰라서 질문이 두가지 있습니다

  1. emplace_back은 일반적인 push_back과 어떻게 다른건가요?
  2. pair를 정렬할 때 기준이 따로 명시되어있지 않은데, 이 경우에는 무엇을 기준으로 정렬되나요? 첫번째 원소 기준 오름차순이어야 논리상 맞아보이긴 하는데 맞나요?

@Sumin-Kim-dev

  1. emplace은 기본적으로 push과 동일한 결과를 만들어냅니다. 다만 push의 경우 push를 할 데이터가 L-valuecopy, R-valuemove를 수행하게 됩니다. emplace의 경우 copymove를 통하지 않고 파라미터로 받은 값들을 통해 오브젝트를 생성해서 바로 넣어주게 됩니다. 사실 시간 차이가 크게 나거나 그런것은 아니지만 의도적으로 사용해주려고 하고 있습니다.
  2. 네 맞습니다. 기본적으로 따로 비교 기준이 없다면 첫 번째 요소 순서대로, 만일 첫 번째 요소가 같다면 두 번째 요소의 순서대로 정렬이 됩니다.

Copy link
Member

@kgh2120 kgh2120 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

저도 이 문제 도전해보려고 해서 풀이를 자세히 못보는 상황이라서 너무 아쉽네요 ㅠㅠ
풀거나 포기한다면... 자세히 봐보겠습니다...

가끔 cpp 코드를 보면 간결하면서 속도도 빨라서 정말 신기하네요..

@minjae9610
Copy link
Member Author

저도 이 문제 도전해보려고 해서 풀이를 자세히 못보는 상황이라서 너무 아쉽네요 ㅠㅠ 풀거나 포기한다면... 자세히 봐보겠습니다...

가끔 cpp 코드를 보면 간결하면서 속도도 빨라서 정말 신기하네요..

@kgh2120 풀고 오실때까지 머지 하지 않고 대기해볼께요 :)
풀고 와서 한번 답 달아주세요 :p

@minjae9610 minjae9610 merged commit 89a353b into main Sep 2, 2023
@minjae9610 minjae9610 deleted the algo/minjae9610/boj13907 branch September 2, 2023 11:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
#Dijkstra #DP 민코딩 민코딩 문제 백준 백준 문제
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants