• POJ 1062


    题意:其实吧,,我也没看懂题意。。还是说一下dijkstra算法,,三个步骤,循环n次

    while(n--)

    {

         在所有未标号节点中,选出d[]值最小的节点

         标记

        松弛所有与这个点相关的所有边

    }

    这个算法的精髓在于,每次找到的最小边都不能被其他节点松弛,只能它去松弛别的节点。这样,就可以打印出来最短路径的遍历顺序了;换种说法就是,每次找到的那个点,都是最有资格去松弛其他节点的点,所以最多循环n次;不可以处理负环

    Bellman 的算法:

    循环n-1次,每次将所有的边松弛一遍;这个算法可以检查是否有负环,当出现负环/正环的时候,还可以继续松弛。

    AC代码:

     1 //dijkstla算法
     2 #include <stdio.h>
     3 #include <string.h>
     4 #include <algorithm>
     5 #define INF 0x3f3f3f3f
     6 using namespace std;
     7 int vis[105],edge[105][105],n,price[105],level[105],d[105];
     8 void init()
     9 {
    10     for(int i=1; i<=n; i++)
    11     {
    12         for(int j=1; j<=n; j++)
    13         {
    14             edge[i][j]=INF;//初始化,要求最短路径,所以先初始化为无穷大
    15         }
    16     }
    17 }
    18 void read()
    19 {
    20     int l,t,tp;
    21     for(int i=1; i<=n; i++)
    22     {
    23         scanf("%d%d%d",&price[i],&level[i],&l);
    24         for(int j=0; j<l; j++)
    25         {
    26             scanf("%d%d",&t,&tp);
    27             edge[t][i]=tp;//存储边的信息的时候,要将能到达的”优惠价格“存起来
    28         }
    29     }
    30 }
    31 int dijkstla()//算法主要分三个步骤,循环n次。1.找出所有节点中最小的2.标记3.松弛所有的与这个节点相关的点。
    32 {
    33     for(int i=1; i<=n; i++)
    34     {
    35         d[i]=price[i];
    36     }
    37     int  pos;
    38     for(int i=1; i<=n; i++)
    39     {
    40         int temp=INF;
    41         for(int j=1; j<=n; j++)
    42         {
    43             if(d[j]<temp&&!vis[j])
    44             {
    45                 temp=d[j];
    46                 pos=j;
    47             }
    48         }
    49         vis[pos]=1;
    50         for(int j=1; j<=n; j++)
    51         {
    52             if(d[j]>d[pos]+edge[pos][j]&&!vis[j])
    53             {
    54                 d[j]=d[pos]+edge[pos][j];
    55             }
    56         }
    57     }
    58     return d[1];
    59 }
    60 int main()
    61 {
    62     int m,ans;
    63     while(~scanf("%d%d",&m,&n))
    64     {
    65         init();
    66         read();
    67         ans=INF;
    68         for(int i=1; i<=n; i++)
    69         {
    70             int min1=level[i];
    71             for(int j=1; j<=n; j++)
    72             {
    73                 if(level[j]<min1||level[j]-min1>m)
    74                 {
    75                     vis[j]=1;
    76                 }
    77                 else
    78                 {
    79                     vis[j]=0;
    80                 }
    81             }
    82             int now=dijkstla();
    83             ans=min(ans,now);
    84         }
    85         printf("%d
    ",ans);
    86     }
    87     return 0;
    88 }
    View Code
  • 相关阅读:
    CentOS查看CPU信息、位数、多核信息
    Linux常用命令大全
    chmod命令详细用法
    tar命令的详细解释
    yum和rpm命令详解
    LeetCode 241. Different Ways to Add Parentheses
    LeetCode 139. Word Break
    LeetCode 201. Bitwise AND of Numbers Range
    LeetCode 486. Predict the Winner
    LeetCode 17. Letter Combinations of a Phone Number
  • 原文地址:https://www.cnblogs.com/qioalu/p/4709176.html
Copyright © 2020-2023  润新知