版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_37360631/article/details/88764065
分析:经典的题目,保证单源最短的情况下,花费最小。
遇到的问题:
(1)前两遍写都遇到了段错误的问题,如最下面的代码所示。原因可能是都调用了递归的方式来打印路径,可能堆栈溢出(调用的次数过多)。
(2)在写dfs的时候,我写通过return step来返回到达目标走的步数,实际上这样是不能返回正确的结果,而正确的写法如下AC代码所示。
(3)当两条路长度相同的时候,注意记得更新花费。
int dfs(int x,int step,int cc){
buf[step]=x;
//cout<<"x= "<<x<<" step= "<<step<<" cc= "<<cc<<endl;
if(x==d &&cc==minSpend){
memcpy(path,buf,sizeof(buf));
return step;
}
for(int i=0;i<n;i++){
if(!visit[i]&&mp[x][i]!=inf){
visit[i]=1;
dfs(i,step+1,cc+spend[x][i]);
visit[i]=0;
}
}
return -1;
}
AC:
#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
#define maxn 510
using namespace std;
int mp[maxn][maxn],spend[maxn][maxn];
int lowcost[maxn],lowspend[maxn],vis[maxn];
int n,m,s,d;
int minSpend,minDis,visit[maxn],ss;
int buf[maxn],path[maxn];
void dijkstra(int s){
for(int i=0;i<n;i++){
lowcost[i]=mp[s][i];
lowspend[i]=spend[s][i];
}
vis[s]=1;
lowcost[s]=0;
lowspend[s]=0;
for(int i=1;i<n;i++){
int v=-1;
int minn=inf;
for(int j=0;j<n;j++){
if(!vis[j]&&lowcost[j]<minn){
minn=lowcost[j];
v=j;
}
}
if(v==-1) break;
vis[v]=1;
for(int j=0;j<n;j++){
if(!vis[j]&&lowcost[v]+mp[v][j]<lowcost[j]){
lowcost[j]=lowcost[v]+mp[v][j];
lowspend[j]=lowspend[v]+spend[v][j];
//pre[j]=v;
}
if(!vis[j]&&lowcost[v]+mp[v][j]==lowcost[j]){
if(lowspend[v]+spend[v][j]<lowspend[j]){
lowspend[j]=lowspend[v]+spend[v][j];
//pre[j]=v;
}
}
}
}
}
void dfs(int x,int step,int cc){
buf[step]=x;
//cout<<"x= "<<x<<" step= "<<step<<" cc= "<<cc<<endl;
if(x==d &&cc==minSpend){
memcpy(path,buf,sizeof(buf));
ss=step;
return ;
}
for(int i=0;i<n;i++){
if(!visit[i]&&mp[x][i]!=inf){
visit[i]=1;
dfs(i,step+1,cc+spend[x][i]);
visit[i]=0;
}
}
}
int main(){
for(int i=0;i<maxn;i++){
for(int j=0;j<maxn;j++){
mp[i][j]=inf;
spend[i][j]=inf;
}
mp[i][i]=0;
spend[i][i]=0;
}
cin>>n>>m>>s>>d;
for(int i=0;i<m;i++){
int x,y,di,co;
cin>>x>>y>>di>>co;
if(mp[x][y]>di){
mp[x][y]=mp[y][x]=di;
}
spend[x][y]=spend[y][x]=co;
}
dijkstra(s);
minDis=lowcost[d];
minSpend=lowspend[d];
visit[s]=1;
dfs(s,0,0);
for(int i=0;i<=ss;i++){
cout<<path[i]<<" ";
}
cout<<minDis<<" "<<minSpend<<endl;
return 0;
}
分析:段错误。
#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
#define maxn 510
using namespace std;
int mp[maxn][maxn],spend[maxn][maxn];
int lowcost[maxn],lowspend[maxn],vis[maxn];
int n,m,s,d;
int pre[maxn];
void dijkstra(int s){
for(int i=0;i<n;i++){
lowcost[i]=mp[s][i];
lowspend[i]=spend[s][i];
}
vis[s]=1;
lowcost[s]=0;
lowspend[s]=0;
for(int i=1;i<n;i++){
int v=-1;
int minn=inf;
for(int j=0;j<n;j++){
if(!vis[j]&&lowcost[j]<minn){
minn=lowcost[j];
v=j;
}
}
if(v==-1) break;
vis[v]=1;
for(int j=0;j<n;j++){
if(!vis[j]&&lowcost[v]+mp[v][j]<lowcost[j]){
lowcost[j]=lowcost[v]+mp[v][j];
lowspend[j]=lowspend[v]+spend[v][j];
pre[j]=v;
}
if(!vis[j]&&lowcost[v]+mp[v][j]==lowcost[j]){
if(lowspend[v]+spend[v][j]<lowspend[j]){
lowspend[j]=lowspend[v]+spend[v][j];
pre[j]=v;
}
}
}
}
}
int main(){
for(int i=0;i<maxn;i++){
for(int j=0;j<maxn;j++){
mp[i][j]=inf;
spend[i][j]=inf;
}
mp[i][i]=0;
spend[i][i]=0;
}
cin>>n>>m>>s>>d;
for(int i=0;i<m;i++){
int x,y,di,co;
cin>>x>>y>>di>>co;
if(mp[x][y]>di){
mp[x][y]=mp[y][x]=di;
}
spend[x][y]=spend[y][x]=co;
}
dijkstra(s);
int minDis=lowcost[d];
int minSpend=lowspend[d];
int b[maxn],pos=0;
pre[s]=-1;
while(pre[d]!=-1){
b[pos++]=d;
d=pre[d];
}
cout<<s<<" ";
for(int i=pos-1;i>=0;i--){
cout<<b[i]<<" ";
}
cout<<minDis<<" "<<minSpend<<endl;
return 0;
}
#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
#define maxn 510
using namespace std;
int mp[maxn][maxn],spend[maxn][maxn];
int lowcost[maxn],lowspend[maxn],vis[maxn];
int n,m,s,d;
int pre[maxn];
void dijkstra(int s){
for(int i=0;i<n;i++){
lowcost[i]=mp[s][i];
lowspend[i]=spend[s][i];
}
vis[s]=1;
lowcost[s]=0;
lowspend[s]=0;
for(int i=1;i<n;i++){
int v=-1;
int minn=inf;
for(int j=0;j<n;j++){
if(!vis[j]&&lowcost[j]<minn){
minn=lowcost[j];
v=j;
}
}
if(v==-1) break;
vis[v]=1;
for(int j=0;j<n;j++){
if(!vis[j]&&lowcost[v]+mp[v][j]<lowcost[j]){
lowcost[j]=lowcost[v]+mp[v][j];
lowspend[j]=lowspend[v]+spend[v][j];
pre[j]=v;
}
if(!vis[j]&&lowcost[v]+mp[v][j]==lowcost[j]){
if(lowspend[v]+spend[v][j]<lowspend[j]){
lowspend[j]=lowspend[v]+spend[v][j];
pre[j]=v;
}
}
}
}
}
void print(int x){
if(x==-1) {return ;}
print(pre[x]);
cout<<x<<" ";
}
int main(){
for(int i=0;i<maxn;i++){
for(int j=0;j<maxn;j++){
mp[i][j]=inf;
spend[i][j]=inf;
}
mp[i][i]=0;
spend[i][i]=0;
}
cin>>n>>m>>s>>d;
for(int i=0;i<m;i++){
int x,y,di,co;
cin>>x>>y>>di>>co;
if(mp[x][y]>di){
mp[x][y]=mp[y][x]=di;
}
spend[x][y]=spend[y][x]=co;
}
dijkstra(s);
int minDis=lowcost[d];
int minSpend=lowspend[d];
//cout<<ans;
pre[s]=-1;
print(pre[d]);
cout<<d<<" ";
cout<<minDis<<" "<<minSpend<<endl;
return 0;
}