1018 Public Bike Management (30 分)

这篇博客探讨了一道涉及最短路径计算的题目,通过Dijkstra算法统计最短路径,并利用DFS进行路径优化。在解决问题时,需要注意初始化路径数组、简化处理自行车数量以及正确设置Dijkstra和DFS的起始与结束节点。
摘要由CSDN通过智能技术生成

Dijkstra+DFS问题,本题涉及到的知识点有,最短路径统计,最短路径记录,路径优化
坑点如下
1,本题首先将所有最短路径统计出来。利用verctor容器
2,利用DFS递归的方法,用vector容器temp将最短路径存储,并进行优化比较,总结出所求路径
3,将bike数目整体减去cmax/2从而简化处理。
4,注意点,在dijkstra中将d数初始化,在主函数中将G数组初始化,dijksra参数为初始结点,DFS参数为终止结点。

代码如下

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<vector>
using namespace std;
const int maxn=510;
const int INF=0x3fffffff;
int G[maxn][maxn];
bool vis[maxn]={false};
int d[maxn];
int minneed=INF,minhave=INF;
int bike[maxn];
int num[maxn];
int cmax,n,sp,m;
struct Node{
    int need;
    int nowhave;
    vector<int>path;  
}node[maxn];
vector<int>pre[maxn],temp,path,ans;
void dijkstra(int s){
    fill(d,d+maxn,INF);
    d[s]=0;
    num[s]=1;
    for(int i=0;i<=n;i++){
      int u=-1,MIN=INF;
      for(int j=0;j<=n;j++){
          if(vis[j]==false&&d[j]<MIN)
          {
              MIN=d[j];
              u=j;
          }
      }
     if(u==-1)return;
     vis[u]=true;
      for(int v=0;v<=n;v++){
        if(vis[v]==false&&G[u][v]!=INF){
            if(d[u]+G[u][v]<d[v]){
                d[v]=d[u]+G[u][v];
                num[v]=num[u];
                pre[v].clear();
                pre[v].push_back(u);
            }
            else if(d[u]+G[u][v]==d[v])
            {   pre[v].push_back(u);  
                num[v]+=num[u]; 
            }
        }  
      }    
    }
}
  void DFS(int v){
      if(v==0){
         temp.push_back(v);
         int neednow=0,havenow=0;
      for(int i=temp.size()-1;i>=0;i--){
         if(bike[temp[i]]>=0){
          havenow+=bike[temp[i]];
         }
         else 
         {
             if(havenow>=abs(bike[temp[i]]))
             {havenow-=abs(bike[temp[i]]);}
             else
             {
              neednow+=(abs(bike[temp[i]])-havenow);
              havenow=0;
             }
         }
     }
          if(neednow<minneed){minneed=neednow;
                              minhave=havenow;
                             ans.clear();
                             ans=temp;}
          else if(neednow==minneed){
              if(havenow<minhave)
              {
                  minhave=havenow;
                  ans.clear();
                  ans=temp;    
              }
          }
          temp.pop_back();
          return;
      }
      temp.push_back(v);
      for(int i=0;i<pre[v].size();i++)
      {DFS(pre[v][i]);}
      temp.pop_back();
  }
int main(){
    scanf("%d%d%d%d",&cmax,&n,&sp,&m);
    int num;
    fill(G[0],G[0]+maxn*maxn,INF);
    for(int i=1;i<=n;i++){
        scanf("%d",&num);
        bike[i]=num-cmax/2;
    }
    for(int i=0;i<m;i++){
        int s1,s2,dis;
        scanf("%d%d%d",&s1,&s2,&dis);
        G[s1][s2]=G[s2][s1]=dis;
    }
    dijkstra(0);
    DFS(sp);
    printf("%d ",minneed);
    for(int i=ans.size()-1;i>=0;i--){
        printf("%d",ans[i]);
        if(i!=0)printf("->"); 
    }
    printf(" %d",minhave); 
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值