校赛T2 个人思路+实现

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


题目概览

        现有小a 小b 约定从起点1出发到终点n,中间的路径形成一张n个点 m给边的无向带权联通图。

        为了增加路途中的趣味性,小a决定和小b玩一个游戏,他们要轮流指定走到的下一条路,走到终点时轮到谁指定怎么走,谁就输了,小a先走。

        因为小a和小b都很聪明,他们只会选择时间花费最小的路去走

一、思路

秉承大胆猜测无需证明(bushi),由题目易得是求从点1到n的单源最短路径(根据时间最小花费可得)

基本上是模板题了,还需要我们实现的是,如何求谁是最终先到终点的那个人?根据题目所给前提:由小a先走,那么最终谁到达终点便是由这条最短路径途径的点的个数所决定

所以解决目标由两个:

        1.求点1到n的单源最短路径

        2.求点1到n的最短路途径点数

二、算法与代码实现

1.链式前向星

最短路算法的基础是图论+搜索

最短路径实际上就是路径花费的最优解,在实现上采用的是BFS即(Breadth-First Search)广度优先搜索除此之外还需实现的是图(graph)的存储

        图的存储有许多方式,邻接表,邻接矩阵等等

        我采用的是算法竞赛中被广为使用的--链式前向星

struct Edge{
     int to,next,w;
}edge[N];
int head[N];
int tot;
void addedge(int u,int v,int w){
     edge[++tot].to=v;
        //终点
     edge[tot].w=w;
        //边权
     edge[tot].next=head[u];
        //以u为起点上一条边的编号,也就是与这个边起点相同的上一条边的编号
     head[u]=tot;
        //更新以u为起点上一条边的编号
}

如果说邻接表是不好写但效率好,邻接矩阵是好写但效率低的话,前向星就是一个相对中庸的数据结构。前向星固然好写,但效率并不高。而在优化为链式前向星后,效率也得到了较大的提升。虽然说,世界上对链式前向星的使用并不是很广泛,但在不愿意写复杂的邻接表的情况下,链式前向星也是一个很优秀的数据结构。                                                                                                                                                                ——摘自《百度百科》

2.SPFA

Shortest Path Faster Algorithm

void SPFA(){
     memset(dis,INF,sizeof(dis));
     memset(vis,0,sizeof(vis));
     q.push(1);
     vis[1]=1;
     dis[1]=0;
     while(!q.empty()){
          int x=q.front();
          q.pop();
          vis[x]=0;
          for(int i=head[x];i;i=edge[i].next){
               int y=edge[i].to,z=edge[i].w;
               if(dis[y]>dis[x]+z){
                    dis[y]=dis[x]+z;
                    if(!vis[x]) q.push(y),vis[y]=1;
               }
          }
     }
}

我们知道

图中一条路径p=(v0, v1, v2, .....,vn)的权重w(p)是构成该路径所有边的权重之和,满足:

                   ​​​​​​​        ​​​​​​​        ​​​​​​​        w(p) = \sum_{i=1}^{k} w(v i-1,v i)

每次边权的更新满足三角不等式性质 与 上界性质(budongbaidu)


总结

比赛时没能完成对最短路 路径数的统计,实际上只需要并查集统计或者反向最短路,将更新命令转换为判断即可,对于上述所讲的数据结构和算法也没有进一步解释,主要还是没什么时间想水篇题解

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值