1018 Public Bike Management - 求符合要求的最短路,並列印
阿新 • • 發佈:2018-12-06
程式碼參考:https://www.liuchuo.net/archives/2373
要注意的問題:
用dijk求最短路的時候,若要記錄最短路是什麼,則用pre陣列,記錄當前節點的前一個節點是什麼,我發現在初始化e陣列的時候,我習慣性的把e[i][i]=0那麼在dijk的鬆弛操作的for迴圈裡,若不加if(j==v)就會報錯,因為這裡把d[0]=d[0]+e[0][0]把0節點的前一個點設為0,這是對的,導致在dfs的時候出錯
d[0]=0; for(int i=0;i<=n;i++){ int v=-1; for(int j=0;j<=n;j++){ if(!vis[j]&&(v==-1||d[j]<d[v])){ v=j; } } vis[v]=1; for(int j=0;j<=n;j++){ if(j==v)continue; if(d[j]>d[v]+e[v][j]){ d[j]=d[v]+e[v][j]; pre[j].clear(); pre[j].push_back(v); } else if(d[j]==d[v]+e[v][j]){ pre[j].push_back(v); } } }
程式碼如下:
#include<iostream> #include<cstdio> #include<algorithm> #include<string> #include<cstring> #include<queue> #include<cmath> #include<set> #include<map> using namespace std; #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 const int INF=0x3f3f3f3f; const int N=510; int minNeed=INF,minBack=INF; int w[N],d[N],e[N][N]; bool vis[N]; vector<int>pre[N]; vector<int>path,temppath; void dfs(int v){ //dfs的目的是找到每條“最短路”的帶的自行車數,和拿回的自行車數,找到符合題意的最短路 temppath.push_back(v); if(v==0){//到0點了,此時這是一條完整的路 int need=0,bac=0; for(int i=temppath.size()-1;i>=0;i--){ int id=temppath[i]; if(w[id]>0){ bac+=w[id]; } else{ if(bac>(0-w[id]))bac+=w[id]; else {need+=(0-w[id]-bac);bac=0;} } } if(need<minNeed){//求能帶的最少的自行車的那一條 minNeed=need; minBack=bac; path=temppath; } else if(need=minNeed&&bac<minBack){//上不成立的話,求能帶回的自行車數目最少的 minBack=bac; path=temppath; } temppath.pop_back();//及時pop return ; } for(int i=0;i<pre[v].size();i++){ dfs(pre[v][i]); } temppath.pop_back();//及時pop } int main(){ int cmax,n,sp,m,a,b; fill(d,d+N,INF); scanf("%d%d%d%d",&cmax,&n,&sp,&m); for(int i=0;i<=n;i++){ for(int j=0;j<=n;j++){ if(i==j)e[i][j]=0; else e[i][j]=INF; } } for(int i=1;i<=n;i++){ scanf("%d",&w[i]); w[i]=w[i]-cmax/2; } for(int i=0;i<m;i++){ int a,b; scanf("%d%d",&a,&b); scanf("%d",&e[a][b]); e[b][a]=e[a][b]; } d[0]=0; for(int i=0;i<=n;i++){ int v=-1; for(int j=0;j<=n;j++){ if(!vis[j]&&(v==-1||d[j]<d[v])){ v=j; } } vis[v]=1; for(int j=0;j<=n;j++){ if(j==v)continue; if(d[j]>d[v]+e[v][j]){ d[j]=d[v]+e[v][j]; pre[j].clear(); pre[j].push_back(v); } else if(d[j]==d[v]+e[v][j]){ pre[j].push_back(v); } } } dfs(sp); printf("%d 0",minNeed); for(int i=path.size()-2;i>=0;i--){ printf("->%d",path[i]); } printf(" %d\n",minBack); } /* 3 5 0 1 4 3 1 3 2 2 2 2 3 1 2 1 3 2 4 2 5 */