Dijkstra+DFS【解题模板】 + 【PAT】1003 Emergency

本题可以AC PAT 1003 Emergency OJ入口

由于在Dijkstra算法中进行进行求解第二标尺的最优值时经常会由于逻辑复杂而浪费很多时间,所以,一般做题的时候为了思路清晰,逻辑清晰常常将求接最短路径和求解最优第二标尺路径分开进行。

也就是先使用Dijkstra进行求解最短路径生产树。

再DFS所有的最短路径求解出符合题目要求的最优路径。

//迪杰斯特拉算法求出最短路径生成树

void Dijkstra(int start) {
	fill(dist, dist + MAX, INF);
	dist[start] = 0;
	for (int i = 0; i < N; i++) {
		int minc = INF,index = -1;
		for (int j = 0; j < N; j++) {
			if (visited[j] == false && minc > dist[j]) {
				minc = dist[j];
				index = j;
			}
		}
		if (index == -1) return;
		visited[index] = true;
		for (int v = 0; v < N; v++) {
			if (visited[v] == false ) {
				if (dist[v] > dist[index] + G[index][v]) {
					dist[v] = dist[index] + G[index][v];
					p[v].clear();
					p[v].push_back(index);
				}
				else if (dist[v] == dist[index] + G[index][v]) {
					p[v].push_back(index);
				}
			}
		}
	}
}

//深度优先遍历最短路径生产树。

vector<int> tempPath, MaxPath;
int num = 0,MaxMen = 0,Men_num = 0;
void DFS(int root,int start) {
	tempPath.push_back(root);
	if (root == start) {
		num++;
		Men_num = 0;
		for (int i = 0; i < tempPath.size(); i++) Men_num += weight[tempPath[i]];
		if (Men_num > MaxMen) {
			MaxMen = Men_num;
			MaxPath = tempPath;
		}
		return;
	}
	for (int i = 0; i < p[root].size(); i++)
	{
		DFS(p[root][i],start);
		tempPath.pop_back();
	}
}

PAT 1003 Emergency AC代码:

#include<bits/stdc++.h>
using namespace std;
const int MAX = 1000;
const int INF = 0x3fffffff;
int G[MAX][MAX],dist[MAX],weight[MAX],w[MAX];
bool visited[MAX];
vector<int> p[MAX];
int N, M, C1, C2;//N为节点数,M为边数。
//迪杰斯特拉算法求出最短路径生成树
void Dijkstra(int start) {
	fill(dist, dist + MAX, INF);
	dist[start] = 0;
	for (int i = 0; i < N; i++) {
		int minc = INF,index = -1;
		for (int j = 0; j < N; j++) {
			if (visited[j] == false && minc > dist[j]) {
				minc = dist[j];
				index = j;
			}
		}
		if (index == -1) return;
		visited[index] = true;
		for (int v = 0; v < N; v++) {
			if (visited[v] == false ) {
				if (dist[v] > dist[index] + G[index][v]) {
					dist[v] = dist[index] + G[index][v];
					p[v].clear();
					p[v].push_back(index);
				}
				else if (dist[v] == dist[index] + G[index][v]) {
					p[v].push_back(index);
				}
			}
		}
	}
}
//深度优先遍历最短路径生产树。
vector<int> tempPath, MaxPath;
int num = 0,MaxMen = 0,Men_num = 0;
void DFS(int root,int start) {
	tempPath.push_back(root);
	if (root == start) {
		num++;
		Men_num = 0;
		for (int i = 0; i < tempPath.size(); i++) Men_num += weight[tempPath[i]];
		if (Men_num > MaxMen) {
			MaxMen = Men_num;
			MaxPath = tempPath;
		}
		return;
	}
	for (int i = 0; i < p[root].size(); i++)
	{
		DFS(p[root][i],start);
		tempPath.pop_back();
	}
}
int main()
{
#ifdef ONLINE_JUDGE
#else
	freopen("Text.txt", "r", stdin);
#endif // ONLINE_JUDGE
	fill(G[0], G[0] + MAX * MAX, INF);
	scanf("%d %d %d %d", &N, &M, &C1, &C2);
	for (int i = 0; i < N; i++) scanf("%d", &weight[i]);
	for (int i = 0; i < M; i++) {
		int u, v, wt;
		scanf("%d %d %d", &u, &v, &wt);
		G[u][v] = G[v][u] = wt;
	}
	Dijkstra(C1);
	DFS(C2,C1);
	cout << num<<" "<<MaxMen;	
}

猜你喜欢

转载自blog.csdn.net/qq_39072627/article/details/107450689