PAT(甲)-----最短路径题解集

考察内容:最短路径

—— —— —— —— —— —— —— —— —— —— —— —— —— ——

1.[A1003] Emergency 25分

2.[A1018] Public Bike Management 30分

3.[A1072] Gas Station 30分

4.[A1087] All Roads Lead to Rome 30分

—— —— —— —— —— —— —— —— —— —— —— —— —— ——

普遍形式

  1. 使用dijkstra求最短路径
  2. 点数范围都较少,使用邻接矩阵存储
  3. 着重点倾向于求最短路径的第二标尺,求输出路径满足:最小/大点权,边权,平均点权,平均边权
  4. 方法 只用dijkstradijkstra+dfs

解法--------------------------------------------------------------------------------------------

1.只用dijkstra

顺便求出第二标尺,第三标尺的模板

//dis[]最短路径
//G[][]边权
//w[]点权和,weight[]点权
//num[]最短路条数
//pt[]到该点的累计顶点数
//pre[]前驱结点
//注意各个数组的初始化
if(book[v]==0)//k未被访问
            {
                if(dis[v]>dis[u]+G[u][v])
                {
                   dis[v]=dis[u]+G[u][v];
                   w[v]=w[u]+weight[v];//加上v处的点权
                   pre[v]=u;
                   pt[v]=pt[u]+1//s->v的顶点数等于s->u的顶点数+1
                   num[v]=num[u];//更新到v点的最短路的条数
                }
                else if(dis[v]==dis[u]+G[u][v])
                {
                    if(w[v]<w[u]+weight[v])
                    {
                        w[v]=w[u]+weight[v];
                        pt[v]=pt[u]+1;
                        pre[v]=u;
                    }
                    else if(w[v]==w[u]+weight[v])
                    {
                    ........
                    }
                    num[k]+=num[u];//最短路的条数
                }
            }
dfs输出路径
void dfs(int v)
{
  if(v==st)
  {
     printf("%d",v);
     return ;
  }
  dfs(pre[v]);
  printf("%d",v);
}

2.dijkstra+dfs

dis[]数组更新时
//
vector<int>pre[MAX];
//
if(dis[v]>dis[u]+G[u][v])
{
   dis[v]=dis[u]+G[u][v];
   pre[v].clear();
   pre[v].push_back(u);
}
else if(dis[v]==dis[u]+G[u][v])
{
   pre[v].push_back(u);
}
dfs模板
//
vector<int>path,temppath;
//
void dfs(int start)
{
     if(v==start)
     {
         temppath.push_back(v);
         .....
         int value//用于计算临时路径temppath的第二标尺的值
         .....
         //计算时注意循环从temppath.size()-1开始,倒叙。
         .....
         if(value 优于 最佳value)
         {
          最佳value=value;
          path=temppath;
         }
         temppath.pop_back();//回溯
         return ;
     }
     temppath.push_back(v);
     for(int i=0;i<pre[v].size();i++)
     {
         dfs(pre[v][i]);
     }
     temppath.pop_back();//回溯
}

---------------------------------------------------------------------------------------------------

A1003 Emergency (25 分)

题意: 求解最短路条数和最短路上的最大点权。


A1018 Public Bike Management (30 分)

题意:求一条最短路径,输出需要从起点携带的自行车数量(min),到达目的车站后需带回的自行车数目(min)。

题解:这题有“陷阱”,首先题意 沿途的所有车站的调整过程必须在前往问题车站的过程中就调整完毕,带回时不准调整,所以 路径上的点*maxc/2-(点权和)取最值是错误的!其次,本题不能只使用dijkstra来解决,因为midneed和minremian在路径的传递上不满足最优子结构(简单的相加过程)。也就是说只有所有的路径都确认之后,才能去选择最小的need和最小的remian.


A1030 Travel Plan (30 分)

题意:求最短路径,最短路的长度,最短路上的最小花费(最小边权)


A1072 Gas Station (30 分)


A1087 All Roads Lead to Rome (30 分)

题意:最短路,最短路径,最短路径下的最大点权,如果路径仍不唯一,平均点权最大的那条。

题解: 1.有涉及一个平均点权,平均点权等于路径上的点权之和除以路径上的顶点数之和,而点权之和是会求的即为w[u],顶点数为pt[u],所以比较v处的平均点权以u为中介点得到的平均点权,更新。2.因为起始顶点的点权没有给出,所以计算平均点权是不计算起始顶点的。3.城市名称与编号的对应可以使用map实现。


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值