• dijkstral改编


    题意:给你包含n个点的连通图,每个点都有一个权值。给定起点和终点。问你起点到终点的最短路条数,并且输出路径最短且权值之和最大的一条路径。

    思路:1.如何根据父节点更新子节点。x,y是父子节点。如果从起点s到父节点x的最短路条数为cnt,则从起点到y的最短路条数也为cnt。如果更新某个点最短路条数的时候,发现这个点原来的最短路条数相同的话就要,再原来最短路条数的基础上再加上这次最短路的条数。

    2.如何更新从起点到某个点的权值路径的权值之和:如果从起点到父节点x的权值之和为w,则从起点到y的权值之和为w加上y节点的自身的权值之和。

    3.L2第一题和L2 26题有一些相同的之处,都是由父节点更新子节点。比如26题父节点的辈分如果是2则子节点的辈分就是在2+1.下面上第一题代码。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<stack>
    #include<cmath>
    #define inf 0x3f3f3f3f
    using namespace std;
    
    int f[1008],ans[1008];//ans数组记录起点到每个点得救援队数量
    int w[1008],a[1008][1008];
    int v[1008],d[1008],fa[1008];//fa数组记录父亲节点
    stack<int> s;
    int N,M,S,D,k=1;
    
    void dijkstra()
    {
        memset(d,0x3f,sizeof d);
        memset(v,0,sizeof v);
        d[S]=0;
        f[S]=1;
        ans[S]=w[S];
        for(int i=0;i<N;i++)
        {
            int x,m=inf;
            for(int j=0;j<N;j++)
            {
                if(!v[j]&&d[j]<m)
                {
                    m=d[j];
                    x=j;
                }
            }
            v[x]=1;
            for(int y=0;y<N;y++)
            {
               if(d[y]>d[x]+a[x][y])
               {
                   f[y]=f[x];//最短路条数
                   d[y]=d[x]+a[x][y];
                   fa[y]=x;
                ans[y]=ans[x]+w[y];
               }
               else if(d[y]==d[x]+a[x][y])
               {
                   f[y]+=f[x];
                   if(ans[y]<ans[x]+w[y])
                   {
                   fa[y]=x;
                   ans[y]=ans[x]+w[y];
                }
               }
            }
        }
    
    }
    
    
    int main()
    {
        scanf("%d%d%d%d",&N,&M,&S,&D);
        for(int i=0;i<N;i++)
        {
        scanf("%d",&w[i]);
        }
    
        memset(a,0x3f,sizeof a);
        for(int i=0;i<1008;i++)
        fa[i]=-1;
        int x,y,z;
        for(int i=0;i<M;i++)
        {
        cin>>x>>y>>z;
        a[x][y]=z;
        a[y][x]=z;
        dijkstra();
        printf("%d %d
    ",f[D],ans[D]);
        s.push(D);
        for(int i=fa[D];i!=-1;i=fa[i])
        {
           s.push(i);
        }
    
        printf("%d",s.top());
        s.pop();
        while(!s.empty())
        {
           printf(" %d",s.top());
           s.pop();
        }
    
        return 0;
    }
  • 相关阅读:
    字符串与Json操作
    默认让IE用最高文档模式浏览网页
    MVC中简单的文件下载代码
    2017年1月22日
    JDK环境变量设置
    如何实现windows命令提示符的tab补全
    win7热点设置
    为什么小米5不能适配win7
    各种错误锦集
    插头DP
  • 原文地址:https://www.cnblogs.com/rainyskywx/p/10615639.html
Copyright © 2020-2023  润新知