首页 > 代码库 > 51nod_1459 最短路 dijkstra 特调参数

51nod_1459 最短路 dijkstra 特调参数

好多基础知识都没补完,只好看到、用到一个赶紧补全一个,并且保证下次需要的时候直接用,不用回来再补;

其实这个算法是在补同余最短路的时候用到的,当时突然发现理解算法导论上的原理甚至有效性证明,但是就是没办法写出来合适的代码。。于是到处寻找可以用来试验最短路径算法的试验场(当时学矩阵快速米的时候也是找了51nod上面的一到基础题作为测试的)来熟悉和不全最短路相关基础知识。

首先是DIJKSTRA 

对于DIJKSTRA首先是个贪心算法,每次从集合中选择一条没有走过的最短路径来作为新的边,到达新的节点。在以当前找到的这条边更新所有可达的边——所谓的松弛操作。

可以证明,在n次这样的松弛操作之后,可以求得单元最短路(具体证明见算法导论)

这题的要求比单元最短路相对更高些,他要求找到最短路且权重最高的路径。因而应当在每次进行松弛操作时进行更新——当且仅当路径长度相同时选择更大的权重,其他时候选择更短的边的权重。

 

DIJKSTRA如下:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 
 4 const long long INF=1e12+233;
 5 const long long MAXN=1e3+233;
 6 long long dp[MAXN];
 7 long long point[MAXN];
 8 long long mon[MAXN];
 9 long long path[MAXN][MAXN];
10 long long n,m,start,end;
11 
12 void init()
13 {
14     cin>>n>>m>>start>>end;
15     memset(mon,0,sizeof(mon));
16     for(int i=0;i<MAXN;++i)
17         for(int j=0;j<MAXN;++j)path[i][j]=INF;
18     for(int i=0;i<n;++i)
19     {
20         cin>>point[i];
21         dp[i]=INF;
22     }
23     for(int i=0;i<m;++i)
24     {
25         int a,b,p;
26         cin>>a>>b>>p;
27         path[a][b]=p;
28         path[b][a]=p;
29     }
30 }
31 int v[MAXN];
32 void dijkstra()
33 {
34     memset(v,0,sizeof(v));
35     int x=start;
36     mon[start]=point[start];
37     dp[start]=0;        //dijkstra初始化,应当以最起始点为0点
38     for(int i=0;i<n;++i)
39     {
40         long long mini=INF;
41         for(int j=0;j<n;++j)
42         {
43             if(!v[j]&&dp[j]<mini)
44             {
45                 x=j;
46                 mini=dp[j];
47             }
48         }v[x]=1;        //标记出现过的点
49         for(int j=0;j<n;++j)
50         {
51             if(!v[j]&&dp[j]>dp[x]+path[x][j])
52             {
53             
54                 mon[j]=mon[x]+point[j];
55             }if(!v[j]&&dp[j]==dp[x]+path[x][j])//注意更新时确保该点没有被走到,否则可能出现重复更新
56             {
57                 mon[j]=max(mon[j],mon[x]+point[j]);
58             }
59             
60             dp[j]=min(dp[x]+path[x][j],dp[j]);
61         }
62     }cout<<dp[end]<<" "<<mon[end]<<endl;
63 }
64 int main()
65 {
66     cin.sync_with_stdio(false);
67     init();
68     dijkstra();
69     return 0;
70 }

 

51nod_1459 最短路 dijkstra 特调参数