PAT 甲级 1003

题目大意就是,给两个点,在求出最短路径有几条的同时,找一条最短路径上能得到的人最多的路径,输出最短路径数和人数

题目链接    https://pintia.cn/problem-sets/994805342720868352/problems/994805523835109376

然后我对这道题的总结:

1.我们可以认为,求最短路径时想到    深搜广搜;单源多源最短路 ;

2.广搜:可以完成 有权图找两个一开始给定的点的最短路径长,(利用队列)

             能做到求解最短路径有几条这个问题,但麻烦

3.深搜:可以完成 有权图找两个一开始给定的点的最短路径长,(利用递归)

              也可以求得有几条路径:当然啦,因为深搜就是一种特别暴力的,从头到尾的遍历各种情况,故在求有几种方法时,如果时间复杂度不超的话,就可以选用深搜

4.单源最短路:这道题我觉得有两个地方不能用单源最短路:

               1)用邻接矩阵来存储图的话,遍历比较耗时间;但是用前向星或是邻接表的话,就特别麻烦:因为题目给的并不是单线路经,故u v之间有路,v u之间也得有路,着两条路径就都得存下来,就,,,,麻烦

但这也提醒我,如果有的题目:强调是单向路径,而且是稀疏图,就考虑用邻接表 作为图的存储的数据结构。

                2)单源最短路径也 能做到求解最短路径有几条这个问题,但麻烦。 

5.多元最短路径:由于题目中的起点终点都是一个样例对应固定下来的一组起点终点,故就不用考虑多源最短路了,虽说多源最短路同样能做到求解最短路径有几条这个问题,但麻烦

ac代码

#include <iostream>
#include <string.h>

using namespace std;

int n,m,c1,c2;
int e[505][505];
int renshu[505];
int book[505];
int cnt,maxnum,mindis;

void dfs(int x,int num,int dis)
{
    if(x==c2)
    {
        if(dis<mindis)
        {
            cnt=1;
            maxnum=num;
            mindis=dis;
        }
        else if (dis==mindis)
        {
            cnt++;
            if(num>maxnum)
            {
                maxnum=num;
            }
        }
        return;
    }
    for(int i=0;i<n;i++)
    {
        if(book[i]==0&&e[x][i]!=0x3f3f3f3f)
        {
            book[i]=1;
            dfs(i,num+renshu[i],dis+e[x][i]);
            book[i]=0;
        }
    }
}

int main()
{
    int a,b,c;
    memset(e,0x3f,sizeof(e));
    memset(book,0,sizeof(book));
    mindis=0x3f3f3f3f;

    cin>>n>>m>>c1>>c2;
    for(int i=0;i<n;i++)
    {
        cin>>renshu[i];
    }
    for(int i=0;i<m;i++)
    {
        cin>>a>>b>>c;
        e[a][b]=c;
        e[b][a]=c;
    }
    book[c1]=1;

    dfs(c1,renshu[c1],0);
    cout<<cnt<<" "<<maxnum<<endl;
    return 0;
}

这有一篇大佬写的迪杰斯特拉算法的题解,如果用广搜的话思路就应该也一样吧,,,,我还没写,先贴上大佬博客链接

https://blog.csdn.net/adventural/article/details/86708790

如果我写完了就把我的贴上来,,,

一下是我理解的大佬(上面博客链接的那位大佬)的思路,和大佬代码节选

主要思路是:在更新一个点时,会有一个num[ ]数组,if (dist[u]+wei < dist[v])    那么到 v 点的路径数就可以一更新为与到 u 点的路径数相同 即 num[v] = num[u];             else if (dist[u]+wei == dist[v])    那么原来到 v 点的路径数还可以保留再加上到 u 点的路径数,两者做和,即为此次更新后的 此时到 v点的路径数。

猜你喜欢

转载自blog.csdn.net/qq_41764621/article/details/87269860