基本思路:
主要有两点:
1.多路径保存问题,主要是vector<int>,来保存每个节点的多个前驱节点;
2.对于逆序前驱数组,采用DFS,枚举每个分支,采用逆序访问进行根节点遍历;
关键点:
上述两个问题;
#include<iostream> #include<fstream> #include<sstream> #include<vector> #include<string> #include<cstring> #include<algorithm> #include<math.h> #include<string.h> using namespace std; const int maxn = 510; const int INF = 100000; int cmax, n, sp, p, m; int sta[maxn]; int ma[maxn][maxn]; bool vis[maxn]; int dis[maxn]; vector<int> pre[maxn]; vector<int> tempPath;//临时路径; vector<int> path;//最终保留路径; int numpath; int minNeed = INF; int minRemain = INF; void dij(int st) { fill(vis, vis + maxn, true); fill(dis, dis + maxn, INF); dis[st] = 0; for (int i = 0; i <= n; i++) { int index = -1; int min = INF; for (int j = 0; j <= n; j++) { //寻找最小节点; if (vis[j]&&min > dis[j]) { min = dis[j]; index = j; } } if (index == -1) return; //进行后续的寻找; vis[index] = false; //cout << 1 << endl; for (int j = 0; j <= n; j++) { if (vis[j] && ma[index][j] != INF) { if (dis[j] > dis[index] + ma[index][j]) { //如果存在更小路径; dis[j] = dis[index] + ma[index][j]; pre[j].clear(); pre[j].push_back(index); } else if (dis[j] == dis[index] + ma[index][j]) { //如果存在相等路径; pre[j].push_back(index); } } } } } void DFS(int v) { if (v == 0) { //v为开始节点, 代表已经到了尽头; tempPath.push_back(v); int need = 0; int remain = 0; for (int i = tempPath.size()-1; i >= 0; i--) { //相当于从根开始遍历节点; int id = tempPath[i]; if (sta[id] > 0) { //需要带走自行车; remain += sta[id]; } else { if (remain > abs(sta[id])) { //如果持有量大于补给; remain -= abs(sta[id]); } else { //需要补充 need += abs(sta[id]) - remain; remain = 0; } } } if (need < minNeed) { minNeed = need; minRemain = remain; path = tempPath; } else if (need == minNeed && remain < minRemain) { minRemain = remain; path = tempPath; } tempPath.pop_back(); return; } tempPath.push_back(v); for (int i = 0; i < pre[v].size(); i++) { DFS(pre[v][i]); } tempPath.pop_back(); } int main(){ int a, b; fill(ma[0], ma[0] + maxn * maxn, INF); cin >> cmax >> n >> sp >> m; sta[0] = 0; for (int i = 1; i <=n ; i++) { cin >> sta[i]; sta[i] -= cmax / 2; } for (int i = 0; i < m; i++) { cin >> a >> b; cin >> ma[a][b]; ma[b][a] = ma[a][b]; } dij(0); DFS(sp); printf("%d ", minNeed); for (int i = path.size() - 1; i >= 0; i--) { printf("%d", path[i]); if (i > 0) printf("->"); } printf(" %d", minRemain); return 0; }
1018 Public Bike Management (30point(s)) 需要二刷 *DFS+DIJ多路径保存问题
原文:https://www.cnblogs.com/songlinxuan/p/12383499.html