版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/hit_shaoqi/article/details/81144839
题目:自行车管理,从根结点出发,或者是带回自行车,或者是带着自行车去,一路上逐一平衡结点的自行车数量,知道最终的结点;要求找出最短路径,如果多条最短路径,就找最短路径中需要带的自行车的数量最少的
原理:
1. 建立邻接矩阵,这个矩阵,从根节点出发,遍历邻接矩阵,得到距离想要更新的结点的最短路径,这个路径也是存在一个vector中,vector类型的数组,vector数组中的元素表示当前结点的各个前驱结点,因此最终的到的vector数组就是多条最短路径。使用dijkstra算法;
这时候已经得到距离目标节点的最短路径了
2. 使用深度优先,从目标节点递归找,直到找到根节点,深度递归中每次到达根节点,都根据对对自行车的数量,选择是否当前的路径,最终就得到了即最短,又最少需求的路径。
代码:
#include <iostream>
#include <algorithm>
#include <vector>
#include <cstdio>
#incldue <cstring>
using namespace std;
const int maxv = 505,INF = 0x3f3f3f3f;
int cost[maxv][maxv];
int dist[maxv];
bool visited[maxv];
vector<int> pre[maxv];//记录最短路径上每个结点的前驱结点
int Cmax,dest,n,m;
void init()
{
for(int i=0;i<n;++i){
for(int j=0;j<n;j++)
{
if(i==j)
cost[i][j] = 0;
else
cost[i][j] = INF;
}
}
memset(visited, false,sizeof(visited))
}
void dijkstra(int v0) // dijkstrra 最短路径算法
{
for(int i=0;i<=n;++i){
dist[i] = cost[v0][i];
if(dist[i] ==INF)
pre[i].clear();
else
pre[i].push_back(v0);
}
visited[v0]=true;
for(int i=0;i<n;++i){
int min_dist = INF,Pos;
for(int j=0;j<=n;++j){//找出距离v0结点最近的结点pos,并记录举例
if(!visited[j]&&dist[j]<min_dist){
pos = j;
min_dist = dist[j];
}
}
visited[pos] = true;
for(int j=0;j<=n;++j){
if(!visited[j] && dist[pos]++cost[pos][j]<dist[j]){
dist[j] = dist[pos]+cost[pos][j];
pre[j].clear();
pre[j].push_back(pos);
}
else if(!visited[j]&&dist[post]+cost[post][j]==dist[j]){
pre[j].push_back(pos);
}
}
}
return;
}
int diff[maxv];
vector <int> tmpPath,resPath;
int minExtra = INF,minNeed = INF;
void DFS(int v){
if(v==0){
tmpPath.push_back(v);//DFS选择
int need = 0,extra = 0;
for(int i=tmpPath.size()-1;i>=0;--i){
int id = tmpPath[i];
if(diff[id]>0)
extra +=diff[id];
else if(diff[id]<0){
if(extra>(-diff[id]))
extra +=diff[id];
else{
need +=(-diff[id]-extra);
extra = 0;
}
}
}
if(need < minNeed){
minNeed = need;
minExtra = extra;
resPath = tmpPath;
}
else if(need== minNeed && extra<minExtra){
minExtra = extra;
resPath = tmpPath;
}
tmpPath.pop_back();
return;
}
//通过v
tmpPath.push_back(v);
//遍历v的前驱结点
for(int i=0;i<pre[v].size();++i)
DFS(pre[v][i]);
//不通过v
tmpPath.pop_back();
return;
}
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
int main(int argc, char** argv) {
cin>>Cmax>>n>>dest>>m;
diff[0]=0;
for(int i=1;i<=n;++i){
cin>>diff[i];
diff[i]-=Cmax>>1;
}
inst st,ed,c;
init();
for(int i=0;i<m;++i)
{
cin>>st>>ed>>c;
cost[st][ed]=cost[ed][st]=c;
}
dijkstra(0);
DFS(dest);
cout<<minNeed;
for(int i = resPath.size()-1;i>=0;--i){
if(i==resPath.size()-1)
cout <<' ';
else
cout << "->";
cout <<resPath[i];
}
cout <<' '<<minExtra<<endl;
return 0;
}