PAT (Advanced Level) 1030 Travel Plan (30 分)

PAT (Advanced Level) 1030 Travel Plan (30 分)
PAT (Advanced Level) 1030 Travel Plan (30 分)
题目概述分析:
最短路径+最少花费,典型dijkstra+dfs,详细分析见pat单车调度

//双边权
//dijkstra处理最短路径
//dfs处理最少cost

#include<bits/stdc++.h>
using namespace std;

const int inf = 9999999;
int n, m, s, d;
int e[510][510], dist[510], cost[510][510];
int totaldist = inf, totalcost = inf;
vector<int> temppath, path, pre[510];
bool visit[510];

//从终点反响搜索到起点
void dfs(int peer)
{   
    temppath.push_back(peer);//记得先加入
    if(peer == s)
    {
        int tempcost = 0;
        int len = temppath.size();
        for(int i = 0; i < len - 1; i++)
            tempcost += cost[temppath[i]][temppath[i+1]];
        if(tempcost < totalcost)
        {
            totalcost = tempcost;
            path = temppath;
        }
        temppath.pop_back();
        return;
    }
    for(int i = 0; i < pre[peer].size(); i++)
        dfs(pre[peer][i]);
    temppath.pop_back();
    return;
}

int main()
{
    cin >> n >> m >> s >> d;
    fill(dist, dist + 510, inf);
    fill(e[0], e[0] + 510 * 510, inf);
    int a, b, p, q;
    for(int i = 0; i < m; i++)
    {
        cin >> a >> b >> p >> q;
        e[a][b] = e[b][a] = p;
        cost[a][b] = cost[b][a] = q;
    }
    
    //dijkstra
    dist[s] = 0;
    
    for(int i = 0; i < n; i++)
    {
        int u = -1, minn = inf;
        //寻找最小的dist
        for(int j = 0; j < n; j++)
        {
            if(dist[j] < minn && visit[j] == false)//记得判断visit
            {
                minn = dist[j];
                u = j;
            }
        }
        
        if(u == -1) break;
        visit[u] = true;
        
        //更新dist
        for(int v = 0; v < n; v++)
        {
            if(visit[v] == false && e[u][v] != inf)
            {
                if(dist[u] + e[u][v] < dist[v])
                {   
                    dist[v] = dist[u] + e[u][v];//记得更新dist
                    pre[v].clear();
                    pre[v].push_back(u);
                }
                else if(dist[u] + e[u][v] == dist[v])
                {
                    pre[v].push_back(u);
                }
            }
        }
    }
    
    totaldist = dist[d];
    dfs(d);
    
    int pathlen = path.size();
    for(int i = 0; i < pathlen; i++)
        cout << path[pathlen - i - 1] << " ";
    
    cout << totaldist << " " << totalcost << endl;
    return 0;
}


总结:
1.注意dfs的结构:先pushbak,再判断,后遍历dfs,最后记得popback和return
2.dijkstra注意判断visit,更新dist

上一篇:Jsp预习


下一篇:2021-7-9 VUE的number\trim\lazy