最短路径 pat1111

#include <iostream>
#include<vector>
//1111
//问题1 不够细心
//2 先后顺序搞清楚
//3 一定要记得初始化
//4 命名 的时候记得清楚一点
//5 审题一定要自习,题目要看完整
using namespace std;
const int N = 510;
const int inf = 1e9;
int n,m,st,ed;
int D[N][N],T[N][N];
int di[N],ti[N];
int vis[N];
vector<int> pre1[N],pre2[N];
vector<int> timePath,ansT,disPath,ansD;
//dis
void dijk1(int s){
       fill(vis,vis +N, 0);        //下次vis 设置两个,这样不会导致因为对vis 初始化
       fill(di,di+N,inf);          //而忘记对d 初始化
       di[s] = 0;
       for(int i = 0; i < n;i++){
              int u = -1, Min = inf;
              for(int j = 0; j < n;j++){
                     if(vis[j]== 0 && di[j]< Min){
                            u=j;
                            Min = di[j];
                     }
              }
              if(u==-1) return;
              vis[u] = 1;
              for(int v = 0;v < n; v++){
                     if(vis[v]== 0 && D[u][v]!=inf){
                          if(di[u] + D[u][v] < di[v]){
                                   di[v] = di[u] + D[u][v];
                                   pre1[v].clear();
                                   pre1[v].push_back(u);
                          }
                          else if(di[u] + D[u][v]==di[v]){
                                   pre1[v].push_back(u);
                          }
                     }
              }
       }
}
//time
void dijk2(int s){
       fill(vis,vis +N, 0);
       fill(ti,ti+N,inf);
       ti[s] = 0;
       for(int i = 0; i < n;i++){
              int u = -1, Min = inf;
              for(int j = 0; j < n;j++){
                     if(vis[j]== 0 && ti[j]< Min){
                            u=j;
                            Min = ti[j];
                     }
              }
              if(u==-1) return;
              vis[u] = 1;
              for(int v = 0;v < n; v++){
                     if(vis[v]== 0 && T[u][v]!=inf){
                          if(ti[u] + T[u][v] < ti[v]){
                                   ti[v] = ti[u] + T[u][v];
                                   pre2[v].clear();
                                  pre2[v].push_back(u);
                          }
                          else if(ti[u] + T[u][v] == ti[v]){
                                   pre2[v].push_back(u);
                          }
                     }
              }
       }
}

int timeMin = inf;
void dfsDis(int v){
       if(v== st){
              disPath.push_back(v);
              int tempTime = 0;
              int len = disPath.size();
              for(int i =1; i<len;i++){
                     int id = disPath[i],idnext = disPath[i-1];
                     tempTime+= T[id][idnext];
              }
              if(tempTime < timeMin){
                     timeMin = tempTime;
                     ansD = disPath;
              }
              disPath.pop_back();
             return ;
       }
       disPath.push_back(v);
       for(int i = 0 ; i < pre1[v].size();i++){
              dfsDis(pre1[v][i]);
       }
       disPath.pop_back();
}
int streetMin = inf;
void dfsTime(int v){
       if(v == st){
              timePath.push_back(v);
              if(timePath.size() < streetMin){
                     streetMin = timePath.size();
                     ansT = timePath;
              }
              timePath.pop_back();
             return ;
       }
       timePath.push_back(v);
       for(int i = 0 ; i < pre2[v].size();i++){
              dfsTime(pre2[v][i]);
       }
       timePath.pop_back();
}
int main()
{
       freopen("1111.txt","r",stdin);
       cin>>n>>m;
       fill(D[0],D[0]+N*N,inf);
       fill(T[0],T[0]+N*N,inf);

       for(int i = 0; i < m;i++){
              int v1,v2,x,length,time;
              cin>>v1>>v2>>x>>length>>time;
              if(x!=1){//双向路径
                     D[v1][v2] =D[v2][v1] = length;
                     T[v1][v2] =T[v2][v1] = time;
              }else{//单向路径
                     D[v1][v2] = length;
                     T[v1][v2] = time;
              }
       }
       cin>>st>>ed;
       dijk1(st);
       dfsDis(ed);
       dijk2(st);
       dfsTime(ed);
       if(ansD == ansT){
              printf("Distance = %d; Time = %d: ",di[ed],ti[ed]);
              for(int i = ansD.size() - 1;i>=0;i--){
                     if(i>0) printf("%d -> ",ansD[i]);
                     else printf("%d",ansD[i]);
              }
       }else{
              printf("Distance = %d: ",di[ed]);
              for(int i = ansD.size() - 1;i>=0;i--){
                     if(i>0) printf("%d -> ",ansD[i]);
                     else printf("%d\n",ansD[i]);
              }
              printf("Time = %d: ",ti[ed]);
              for(int i = ansT.size() - 1;i>=0;i--){
                     if(i>0) printf("%d -> ",ansT[i]);
                     else printf("%d\n",ansT[i]);
              }
       }


    //cout << "Hello world!" << endl;
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值