zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    台州 OJ 3847 Mowing the Lawn 线性DP 单调队列
    洛谷 OJ P1417 烹调方案 01背包
    快速幂取模
    台州 OJ 2649 More is better 并查集
    UVa 1640
    UVa 11971
    UVa 10900
    UVa 11346
    UVa 10288
    UVa 1639
  • 原文地址:https://www.cnblogs.com/rainyskywx/p/10615639.html
Copyright © 2011-2022 走看看