PAT最短路径问题简单总结

在PAT甲级真题目录中,涉及到最短路经问题求解的有1003、1018、1030、1087、1111。

一般来说,可以用最短路径算法(dijkstra、SPFA等)加上DFS进行求解。

我一般用这些数据结构:

struct node{
    int v;//与该地点相连的地点的序号
    int cost;//两个地点之间的距离
    //...由题意确定需要增加变量
    node(int v,int cost):v(v),cost(cost){ }
}
vector<node> g[maxn];//邻接表的形式存储图
vector<int> pre[maxn];//在求解最短路径时记录前序节点,用于后续的dfs求解
int d[maxn];//最短路算法中的d
int vis[maxn];//是否访问过
vector<int> path,temppath;//在dfs中记录路径
//...视情况增加需要的变量

1.在main函数中依次读入点数、边数、起点、终点;再读入边的信息,完成输入。

2.求解最短路径,当权值为非负时,使用dijkstra O(n^2),当权值有负但没有负圈时可以用SPFA O(kE),SPFA能检测负圈,不过PAT上的数据没那么难,dijkstra通常都能在规定时间内求出解,不过我还是喜欢用SPFA。

如果题目要求输出路径的话,在进行松弛操作的时候,需要记录下节点的前序节点

if(d[v]>d[cur]+cost){
    d[v]=d[cur]+cost;
    pre[v].clear();
    pre[v].push_back(cur);
    //...
}
else if(d[v]==d[cur]+cost){
    pre[v].push_back(cur);
}
//如果题目上写:若存在多条长度相同的最短路径,输出耗时最短的路径(保证唯一)
//那么可以再增加一个变量 int weight[maxn]
//因为路径唯一,可以直接用 int pre[maxn]来记录前序节点,就不需要用vector了,后续的dfs也省事
if(d[v]>d[cur]+cost){
    d[v]=d[cur]+cost;
    weight[v]=weight[cur]+time;
    pre[v]=cur;
    //...
}
else if(d[v]==d[cur]+cost&&weight[v]>weight[cur]+time){
    weight[v]=weight[cur]+time;
    pre[v]=cur;
}

3.求解需要输出的路径,由于最短路径不唯一,需要根据题目要求来输出,这时候一般就用dfs。

void dfs(int cur){//因为pre数组记录了前序节点,所以从后往前找
    temppath.push_back(cur);
    if(cur==s){//当前节点为开始节点
        //这时temppath已经记录下了一条完整的路径,根据题目要求来
        if(temppath符合要求)
            path=temppath;
    }
    else{
        for(int i=0;i<pre[cur].size();i++)
            dfs(pre[cur][i]);
    }
    temppath.pop_back();//别忘了回到之前状态
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值