题目七

题目:无向图中,求图中从src节点到dest节点的最短路径,若最短路径相同,则求最少代价的路径
–对于图的算法还不是很熟悉,这道题目当做参考–
参考代码一:

#include <iostream>
 
#include <string>
 
#include <vector>
 
#include <algorithm>
 
using namespace std;
 
int const MaxVertexNum = 500;
 
#define INFINITY 65535
 
#define Vertex int
 
#define WeightType int
 
//***********边的定义*************//
 
struct Enode{
 
    Vertex V1,V2;
 
    WeightType Weight;
 
    WeightType Money;
 
};
 
typedef Enode *Edge;
 
//*************图节点定义************//
 
struct Gnode{
 
    int Nv;//顶点数
 
    int Ne;//边数
 
    WeightType G[MaxVertexNum][MaxVertexNum];  //用了邻接矩阵
 
    WeightType M[MaxVertexNum][MaxVertexNum];
 
};
 
typedef Gnode *MGraph;
 
//***************函数声明*****************//
 
MGraph CreateGraph(int VertexNum);
 
void InsertEdge(MGraph Graph, Edge E);
 
MGraph BuildGraph(Vertex &S, Vertex &D);
 
Vertex FindMinDist(MGraph Graph, int dist[],int collected[]);
 
bool Dijkstra(MGraph Graph, int dist[],int path[],int cost[],Vertex S);
 
void FindThePathOut(MGraph Graph,Vertex S,Vertex D);
 
 
 
int main(){
 
    MGraph Graph;
 
    Vertex S,D;
 
    Graph = BuildGraph(S, D);
 
    FindThePathOut(Graph, S, D);
 
    return 0;
 
}
 
//*****************以下是建立图数据结构*****************//
 
MGraph CreateGraph(int VertexNum){
 
    MGraph Graph;
 
    Graph = new Gnode;
 
    Graph->Nv = VertexNum;
 
    Graph->Ne = 0;
 
    for (Vertex V=0; V < Graph->Nv; ++V) {
 
        for (Vertex W=0; W < Graph->Nv; ++W) {
 
            Graph->G[V][W] = INFINITY;
 
            Graph->M[V][W] = INFINITY;
 
        }
 
    }
 
    return Graph;
 
}
 
void InsertEdge(MGraph Graph, Edge E){     //注意是无向图
 
    Graph->G[E->V1][E->V2] = E->Weight;
 
    Graph->M[E->V1][E->V2] = E->Money;
 
    Graph->G[E->V2][E->V1] = E->Weight;
 
    Graph->M[E->V2][E->V1] = E->Money;
 
}
 
MGraph BuildGraph(Vertex &S,Vertex &D){
 
    MGraph Graph;
 
    Edge E;
 
    Vertex Nv;
 
    cin >> Nv;
 
    Graph = CreateGraph(Nv);
 
    cin >> Graph->Ne >> S >> D;
 
 
 
    if (Graph->Ne != 0) {
 
        E = new Enode;
 
        for (int i=0; i < Graph->Ne; ++i) {
 
            cin >> E->V1 >> E->V2 >> E->Weight >> E->Money;
 
            InsertEdge(Graph, E);
 
        }
 
    }
 
    return Graph;
 
}
 
//*********************建立图结束*******************//
 
//*********************以下是最短路径算法**********************//
 
bool Dijkstra(MGraph Graph, int dist[],int path[],int cost[],Vertex S){
 
    int collected[Graph->Nv];   //存放已找到最短路径的节点
 
    Vertex V;
 
    for (V=0; V < Graph->Nv; ++V) {
 
        dist[V] = Graph->G[S][V];
 
        cost[V] = Graph->M[S][V];
 
        path[V] = S;
 
        collected[V] = false;
 
    }
 
    dist[S] = 0;cost[S] = 0;collected[S] = true;
 
    while (true) {
 
        V = FindMinDist(Graph, dist, collected);   //每轮从上一轮最短的那个节点出发
 
        if (V == -1) {
 
            break;
 
        }
 
        collected[V] = true;
 
        for (Vertex W=0; W < Graph->Nv; ++W) {
 
            if (collected[W]==false && Graph->G[V][W] < INFINITY) {
 
                if (Graph->G[V][W] < 0) {
 
                    return false;
 
                }
 
                if (dist[V] + Graph->G[V][W] < dist[W]) {
 
                    dist[W] = dist[V] + Graph->G[V][W];
 
                    path[W] = V;  //path记录到达节点w的最短路径中的w的前一个节点
 
                    cost[W] = cost[V] + Graph->M[V][W];
 
                }
 
                else if (dist[V]+Graph->G[V][W]==dist[W] && cost[V]+Graph->M[V][W]<cost[W]){
 
                    dist[W] = dist[V] + Graph->G[V][W];
 
                    path[W] = V;
 
                    cost[W] = cost[V] + Graph->M[V][W];
 
                }
 
            }
 
        }
 
    }
 
    return true;
 
}
 
Vertex FindMinDist(MGraph Graph,int dist[],int collected[]){
 
    Vertex MinV=0;
 
    int MinDist = INFINITY;
 
    for (Vertex V=0; V < Graph->Nv; ++V) {
 
        if (collected[V] == false && dist[V] < MinDist) {
 
            MinDist = dist[V];
 
            MinV = V;
 
        }
 
    }
 
    if (MinDist < INFINITY) {
 
        return MinV;
 
    }
 
    else{
 
        return -1;
 
    }
 
}
 
//********************最短路劲算法结束**********************//
 
void FindThePathOut(MGraph Graph,Vertex S,Vertex D){
 
    int dist[Graph->Nv];
 
    int path[Graph->Nv];
 
    int cost[Graph->Nv];
 
    Dijkstra(Graph, dist, path, cost, S);    //dist是路径代价,path是成本代价
 
     
    vector<Vertex> ThePath;
 
    Vertex P = D;
 
    ThePath.push_back(P);
 
    while (P != S) {
 
        ThePath.push_back(path[P]);
 
        P = path[P];
 
    }
 
    for (auto it = ThePath.rbegin(); it != ThePath.rend(); ++it) {
 
        cout << *it << ' ';
 
    }
 
    cout << dist[D] << ' ' << cost[D] << endl;
 
}
参考代码二:
链接:https://www.nowcoder.com/questionTerminal/18972bbc26f84eb7847e5f92ec0ae1c4
来源:牛客网

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
const int maxn=510;
const int INF=10000000;
bool vis[maxn]={false};
int n,m,start,final,G[maxn][maxn],d[maxn];
int cost[maxn][maxn],c[maxn],pre[maxn];    //cost为对应的边的花费,c记录最小花费
void Dijkstra(int s){
    fill(d,d+maxn,INF);d[s]=0;             //初始化d,c,pre
    fill(c,c+maxn,INF);c[s]=0;
    for(int i=0;i<n;i++) pre[i]=i;
    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){
                u=j;min=d[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];
                    c[v]=c[u]+cost[u][v];
                    pre[v]=u;
                }       
                else if(d[u]+G[u][v]==d[v]&&c[u]+cost[u][v]<c[v]){
                    c[v]=c[u]+cost[u][v];
                    pre[v]=u;
                }
            }
        }
    }
}
void print(int v){   //打印路径
    if(v==start){
        cout<<v<<" ";
        return;
    }
    print(pre[v]);
    cout<<v<<" ";
}
int main(){
    cin>>n>>m>>start>>final;
    int u,v;
    fill(G[0],G[0]+maxn*maxn,INF);
    for(int i=0;i<m;i++){
        cin>>u>>v;
        cin>>G[u][v]>>cost[u][v];
        G[v][u]=G[u][v];
        cost[v][u]=cost[u][v];
    }
    Dijkstra(start);
    print(final);   //打印路径
    cout<<d[final]<<" "<<c[final];
    return 0;
}

评注:dijstera算法中,d[]数组和pre数组是关键

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值