L2-001:dijskstra + 多条最短路径 + 记录中间路径

题目链接:https://pintia.cn/problem-sets/994805046380707840/problems/994805073643683840

思路:

dijkstra算出最短路径,在搜寻最短路时更改一下几点:
1.记录中间路径节点
2.更新最短路时,更新点权和,记录当前节点的最短路数量。

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#define inf 0x3f3f3f3f
using namespace std;
const int N=555;
int dis[N];//记录最短距离 
int path[N];//记录最短路径中间节点 
int w[N];
int pathnum[N];//记录最短路径的数目 
int tol[N];//记录总路径的边权之和 
int book[N];
int mp[N][N];//邻接矩阵 
int n,m,s,d;

void print(int x)//递归输出路径
{
    if(path[x]==-1)
    {
        printf("%d",x);
        return ;
    }
    print(path[x]);
    printf(" %d",x);
    return ;
}

void dijkstra()
{
    memset(book,0,sizeof(book));
    memset(tol,0,sizeof(tol));
    int i,j;
    for(i=0;i<n;i++)
        dis[i]=inf;
    dis[s]=0;
    path[s]=-1;
    tol[s]=w[s];//对起始点的初始化
    pathnum[s]=1;//起点的最短路径数为1
    
    for(i=0;i<n;i++)
    {
        int u,minn=inf;
        //找到dis路径权值最小的点u 
        for(j=0;j<n;j++)
        {
            if(!book[j]&&dis[j]<minn)
            {
                u=j;
                minn=dis[j];
            }
        }
        book[u]=1;
        for(j=0;j<n;j++)
        {
            //更新最短路径 以u去更新它的邻接点 
            if(dis[j] > dis[u] + mp[u][j])//松弛时各数组的更新
            {
                dis[j] = dis[u] + mp[u][j];//更新最短路径值 ok 
                path[j] = u;//记录中间路径 ok 
                tol[j] = tol[u] + w[j]; //更新最短路径对应下的顶点最大值 
                pathnum[j] = pathnum[u];//如果dis最短路径的值更新为最大值了 说明是第一次更新,并且是用u去更新的v,所以点j的最短路径数量应该等于u的最短路径数量 
            }
            else if(dis[j] == dis[u] + mp[u][j])//相等时的更新
            {
                pathnum[j] += pathnum[u];//如果最短路径相等了,说明有这两个点的多种方案都可行,应该是二者最短路径的和
                
                //在距离相同时 比较所有的点权和 更新为最大的点权 
                if(tol[j] < tol[u] + w[j])//点权值的更新
                {
                    tol[j] = tol[u] + w[j];//更新点权值和
                    path[j] = u;//改变中间路径 
                }
            }
        }
    }
}

int main()
{
    int x,y,z;
    scanf("%d%d%d%d",&n,&m,&s,&d);
    for(int i=0;i<n;i++)
        scanf("%d",&w[i]);
    memset(mp,inf,sizeof(mp));
    for(int i=0;i<m;i++)
    {
        scanf("%d%d%d",&x,&y,&z);
        mp[x][y]=z;
        mp[y][x]=mp[x][y];
    }
    dijkstra();
    printf("%d %d\n",pathnum[d],tol[d]);
    print(d);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/fisherss/p/10422114.html