우선 순위 대기열 구현 Dijie Tesla 템플릿

  Dijkstra는 여전히 가장 일반적으로 사용되는 최단 경로 알고리즘입니다. 데이터 구조에 대한 이전 연구에서 작성한 코드는 매우 중복되어 기억이 나지 않습니다. 오늘 시간이 있다면 간결한 템플릿을 만들어 봅시다!
  구현 방법은 우선 순위 대기열에 해당하며 템플릿에는 매핑 방법이 포함되어 있습니다 (사실 모든 종류의 방법이 좋습니다). 이 기사에서는 다음을 사용합니다.

vector< unordered_map<int, int>> graph(n); // 本质是邻接表

  템플릿은 다음과 같습니다

void DIJ() {
    
    
	/* 建图,建图方式有几种,尽量使用邻接表
	 *	1.vector<vector<int>> graph(n) // 临界矩阵
	 *	2.vector<unordered_map<int,int>> // 邻接表,map中first代表指向,second代表权值
	*/ 
	// 假设有vector<vector<int>>  edges提供边的信息,[1,2,3]代表1->2,权值为3
	vector<unordered_map<int, int>> graph(n);
	for (int i=0; i<edges.size(); i++) {
    
    
		int u = edges[i][0];
		int v = edges[i][1];
		int w = edges[i][2];
		graph[u-1][v-1] = w; // -1的原因是索引从0开始
		graph[v-1][u-1] = w; // 看清问题是单向图还是双向图,决定了写几个
	}
	
	vector<int> dis(n, INT_MAX);
	priority_queue<pair<int, int>, vector<pair<int, int> > > q;
	// 起点编号设置为start
	dis[start] = 0;
	q.push(start, 0);
	while (!q.empty()) {
    
    
		pair<int, int> tp = q.top();
		int id = tp.first;
		int distance = tp.second;
		q.pop();
		// 这里用指针吧,用graph[id][i].first会报错,不知道为啥
		for (auto it=graph[id].begin(); it != graph[id].end(); it++) {
    
    
			int new_id = it->first;
			int new_distance = it->second;
			if (dis[id]+new_distance < dis[new_id]) {
    
    
				dis[new_id] = dis[id] + new_distance;
				q.push(make_pair(new_id, -dis[new_id])); // 传入负值,实现从小到大排列 
			}
		}
	}
}
// dis数组中得到的就是起点到各个节点的最短距离了,如果不达就会是INT_MAX

  가짜 스타일을 연습하지 말라고 말하고 두 개의 샘플 질문으로 템플릿을 시도해 봅시다!

연습 1 : P1339 [USACO09OCT] Heat Wave G

P1339 [USACO09OCT] 열파 G

AC 코드는 다음과 같습니다.

#include<bits/stdc++.h>
using namespace std;

int main(void) {
    
    
	int n,m,s,t;
	cin >> n >> m >> s >> t;
	vector<unordered_map<int,int> > graph(n);
	for (int i=0; i<m; i++) {
    
    
		int u,v,w;
		cin >> u >> v >>w;
		graph[u-1][v-1] = w;
		graph[v-1][u-1] = w;
	}
	vector<int> dis(n, INT_MAX);
	priority_queue<pair<int, int>, vector<pair<int, int>>> q;
	dis[s-1] = 0;
	q.push(make_pair(s-1,0));
	while (!q.empty()) {
    
    
		pair<int, int> tp = q.top();
		int id = tp.first;
		int distance = tp.second;
		q.pop();
		for (auto it=graph[id].begin(); it != graph[id].end(); it++) {
    
    
			int new_id = it->first;
			int new_distance = it->second;
			if (dis[id] + new_distance < dis[new_id]) {
    
    
				dis[new_id] = dis[id] + new_distance;
				q.push(make_pair(new_id, -dis[new_id]));
			}
		}
	}
	cout << dis[t-1];
	return 0;
}

연습 2 : P3371 【템플릿】 단일 소스 최단 경로 (약화 버전)

P3371 [템플릿] 단일 소스 최단 경로 (약화 된 버전)
  실제로이 코드는 테스트를 완전히 통과하지 못했지만 템플릿에 따라 작성되었습니다. 샘플을 전달할 수 있습니다. 무슨 일이 일어나고 있는지 모르겠습니다. 지나가는 신들의 질문에 답할 수 있도록 도와주세요. 코드를 먼저 첨부하세요. 나중에 발생할 수도 있나요?

코드 쇼 :

#include<bits/stdc++.h>
using namespace std;
int main(void) {
    
    
	int n, m, s;
	cin >> n >> m >> s;
	vector<unordered_map<int, int>> graph(n);
	for (int i=0; i<m; i++) {
    
    
		int u,v,w;
		cin >> u >> v >> w;
		graph[u-1][v-1] = w;
	}
	vector<int> dis(n, INT_MAX);
	priority_queue<pair<int,int>,vector<pair<int,int>>> q;
	dis[s-1] = 0;
	q.push(make_pair(s-1, 0));
	while (!q.empty()) {
    
    
		pair<int, int> pa = q.top();
		int id = pa.first;
		int distance = pa.second;
		q.pop();
		for (auto it=graph[id].begin(); it!=graph[id].end(); it++) {
    
    
			int new_id = it->first;
			int new_distance = it->second;
			if (dis[id]+new_distance < dis[new_id]) {
    
    
				dis[new_id] = dis[id]+new_distance;
				q.push(make_pair(new_id, -dis[new_id]));
			}
		}
	}
	for (int i=0; i<n; i++) {
    
    
		if (i != n-1)
			cout << dis[i] << " ";
		else
			cout << dis[i];
	}
	return 0;
}

  사실 실제 그래프 주제 인 DIJ는 그 일부일 뿐이므로, 큰 문제를 천천히 해결하기를 바라면서 부분적으로 마스터하세요 hhh!

참고 자료 :
Dijkstra의 알고리즘 상세 설명 + 템플릿 + 샘플 질문

추천

출처blog.csdn.net/gls_nuaa/article/details/115057519