• 最短路 dijkstra 优先队列


    1.裸题 hdu2544

    http://acm.hdu.edu.cn/showproblem.php?pid=2544

    Way1:

    好像不对

     1 #include <cstdio>
     2 #include <cstdlib>
     3 #include <cmath>
     4 #include <cstring>
     5 #include <stdbool.h>
     6 #include <set>
     7 #include <vector>
     8 #include <map>
     9 #include <queue>
    10 #include <algorithm>
    11 #include <iostream>
    12 using namespace std;
    13 #define maxn 100+5
    14 #define inf 1e9
    15 
    16 long dist[maxn],road[maxn][maxn];
    17 bool vis[maxn];
    18 struct cmp
    19 {
    20     bool operator() (long a,long b)
    21     {
    22         return dist[a]>dist[b];
    23     }
    24 };
    25 priority_queue<long,vector<long>,cmp> f;
    26 
    27 int main()
    28 {
    29     long n,m,i,j,x,y,z,d;
    30     while (1)
    31     {
    32         scanf("%ld%ld",&n,&m);
    33         if (n==0 && m==0)
    34             break;
    35         for (i=1;i<=n;i++)
    36             for (j=1;j<=n;j++)
    37                 road[i][j]=inf;
    38         for (i=1;i<=m;i++)
    39         {
    40             scanf("%ld%ld%ld",&x,&y,&z);
    41             road[x][y]=min(road[x][y],z);
    42             road[y][x]=road[x][y];
    43         }
    44         for (i=1;i<=n;i++)
    45         {
    46             vis[i]=false;
    47             dist[i]=inf;
    48         }
    49         dist[1]=0;
    50         //pay attention!
    51         while (!f.empty())
    52             f.pop();
    53         f.push(1);
    54         for (j=1;j<n;j++) //use 'i' wrong!
    55         {
    56             while (vis[f.top()])
    57                 f.pop();
    58             d=f.top();
    59             if (d==n)
    60                 break;
    61             vis[d]=true;
    62             f.pop();
    63             
    64             for (i=1;i<=n;i++)
    65                 if (!vis[i] && dist[i]>dist[d]+road[i][d])
    66                 {
    67                     dist[i]=dist[d]+road[i][d];;
    68                     f.push(i);
    69                 }
    70         }
    71         printf("%ld
    ",dist[n]);
    72     }
    73     return 0;
    74 }
    75 /*
    76 6 7
    77 1 2 10
    78 1 2 3
    79 1 3 1
    80 2 4 3
    81 4 5 1
    82 5 6 10
    83 2 5 1
    84 */

    Way2:

    自行写堆,让堆中的值减小(路径长度减小),在堆中上升。

    只要掌握了合理的写法,其实也不是特别不好理解和难写

      1 #include <cstdio>
      2 #include <cstdlib>
      3 #include <cmath>
      4 #include <cstring>
      5 #include <stdbool.h>
      6 #include <set>
      7 #include <vector>
      8 #include <map>
      9 #include <queue>
     10 #include <algorithm>
     11 #include <iostream>
     12 using namespace std;
     13 #define maxn 10000+5
     14 #define inf 1e9
     15 
     16 //pos[i]:编号为i的城市到起点的距离 在 树中的位置 
     17 long dist[maxn],road[maxn][maxn],tree[maxn],pos[maxn],g=0;
     18 bool vis[maxn];
     19 
     20 //minimum-heap
     21 void up(long i)
     22 {
     23     long j,temp;
     24     while (i>1)
     25     {
     26         j=i>>1;
     27         //i>j
     28         if (dist[tree[i]]<dist[tree[j]])
     29         {
     30             temp=tree[i];
     31             tree[i]=tree[j];
     32             tree[j]=temp;
     33             pos[tree[i]]=i;
     34             pos[tree[j]]=j;
     35         }
     36         else
     37             break;
     38         i=j;
     39     }
     40 }
     41 
     42 void down(long i)
     43 {
     44     long j,temp;
     45     while ((i<<1)<=g)
     46     {
     47         j=i<<1;
     48         if (dist[tree[j+1]]<dist[tree[j]])
     49             j++;
     50         //i<j
     51         if (dist[tree[i]]>dist[tree[j]])
     52         {
     53             temp=tree[i];
     54             tree[i]=tree[j];
     55             tree[j]=temp;
     56             pos[tree[i]]=i;
     57             pos[tree[j]]=j;
     58         }
     59         else
     60             break;
     61         i=j;
     62     }
     63 }
     64 
     65 int main()
     66 {
     67     long n,m,i,j,x,y,z,d;
     68     while (1)
     69     {
     70         scanf("%ld%ld",&n,&m);
     71         if (n==0 && m==0)
     72             break;
     73         for (i=1;i<=n;i++)
     74             for (j=1;j<=n;j++)
     75                 road[i][j]=inf;
     76         for (i=1;i<=m;i++)
     77         {
     78             scanf("%ld%ld%ld",&x,&y,&z);
     79             road[x][y]=min(road[x][y],z);
     80             road[y][x]=road[x][y];
     81         }
     82         for (i=1;i<=n;i++)
     83         {
     84             vis[i]=false;
     85             dist[i]=-1;
     86         }
     87         dist[1]=0;
     88         g=1;
     89         tree[1]=1;
     90         pos[1]=1;
     91         for (j=1;j<n;j++) //use 'i' wrong!
     92         {
     93             d=tree[1];
     94             if (d==n)
     95                 break;
     96             tree[1]=tree[g];
     97             pos[tree[1]]=1;
     98             g--;
     99             down(1);
    100             
    101             vis[d]=true;
    102             for (i=1;i<=n;i++)
    103                 if (!vis[i])
    104                 {
    105                     if (dist[i]==-1)
    106                     {
    107                         dist[i]=dist[d]+road[i][d];
    108                         g++;
    109                         tree[g]=i;
    110                         pos[i]=g;
    111                         up(g);
    112                     }
    113                     else if (dist[i]>dist[d]+road[i][d])
    114                     {
    115                         dist[i]=dist[d]+road[i][d];
    116                         up(pos[i]);                        
    117                     }
    118                 }
    119         }
    120         printf("%ld
    ",dist[n]);
    121     }
    122     return 0;
    123 }
    124 /*
    125 6 7
    126 1 2 10
    127 1 2 3
    128 1 3 1
    129 2 4 3
    130 4 5 1
    131 5 6 10
    132 2 5 1
    133 */

    2.多关键字

    L3-011. 直捣黄龙

    https://www.patest.cn/contests/gplt/L3-011

      1 #include <cstdio>
      2 #include <cstdlib>
      3 #include <cstring>
      4 #include <cmath>
      5 #include <stdbool.h>
      6 #include <set>
      7 #include <vector>
      8 #include <map>
      9 #include <queue>
     10 #include <stack>
     11 #include <algorithm>
     12 #include <iostream>
     13 using namespace std;
     14 #define maxn 200+5
     15 #define inf 1e9
     16 
     17 struct node
     18 {
     19     long kill,dist,free,count;
     20 }point[maxn];
     21 
     22 struct cmp
     23 {
     24     bool operator() (long a,long b)
     25     {
     26         return point[a].dist>point[b].dist;
     27     }
     28 };
     29 priority_queue<long,vector<long>,cmp> f;
     30 
     31 long road[maxn][maxn],kill[maxn],pre[maxn],n;
     32 char s[maxn][5];
     33 bool vis[maxn];
     34 
     35 long find(char ss[])
     36 {
     37     long i;
     38     for (i=1;i<=n;i++)
     39         if (strcmp(s[i],ss)==0)
     40             return i;
     41 }
     42 
     43 void print(long d)
     44 {
     45     if (pre[d]!=-1)
     46     {
     47         print(pre[d]);
     48         printf("->%s",s[d]);
     49     }
     50     else
     51         printf("%s",s[d]);
     52 }
     53 
     54 int main()
     55 {
     56     char s1[5],s2[5];
     57     long m,i,j,d,x,y,e;
     58     scanf("%ld%ld%s%s",&n,&m,s1,s2);
     59     for (i=1;i<=n;i++)
     60     {
     61         point[i].dist=inf;
     62         vis[i]=false;
     63     }
     64     for (i=1;i<=n;i++)
     65         for (j=1;j<=n;j++)
     66             road[i][j]=inf+1;
     67     point[n].kill=0;
     68     strcpy(s[n],s1);
     69     pre[n]=-1;
     70     point[n].dist=0;
     71     point[n].free=0;
     72     point[n].count=1;
     73     f.push(n);
     74     for (i=1;i<n;i++)
     75     {
     76         scanf("%s%ld",s[i],&kill[i]);
     77         if (strcmp(s2,s[i])==0)
     78             e=i;
     79     }
     80     for (i=1;i<=m;i++)
     81     {
     82         scanf("%s%s%ld",s1,s2,&d);
     83         x=find(s1);
     84         y=find(s2);
     85         road[x][y]=min(road[x][y],d);
     86         road[y][x]=road[x][y];
     87     }
     88     for (j=1;j<n;j++)
     89     {
     90         while (vis[f.top()])
     91             f.pop();
     92         d=f.top();
     93         if (d==e)
     94             break;
     95         vis[d]=true;
     96         for (i=1;i<=n;i++)
     97             if (!vis[i])
     98             {
     99                 if (point[i].dist>point[d].dist+road[i][d])
    100                 {
    101                     pre[i]=d;
    102                     point[i].count=point[d].count;
    103                     point[i].dist=point[d].dist+road[i][d];
    104                     point[i].free=point[d].free+1;
    105                     point[i].kill=point[d].kill+kill[i];
    106                     f.push(i);
    107                 }
    108                 else if (point[i].dist==point[d].dist+road[i][d])
    109                 {
    110                     point[i].count+=point[d].count;
    111                     if ((point[i].free<point[d].free+1) || 
    112                         (point[i].free==point[d].free+1 && point[i].kill<point[d].kill+kill[i]))
    113                     {
    114                         pre[i]=d;                        
    115                         point[i].free=point[d].free+1;
    116                         point[i].kill=point[d].kill+kill[i];
    117                         f.push(i);
    118                     }
    119                 }
    120             }
    121     }
    122     print(e);
    123     printf("
    %ld %ld %ld
    ",point[e].count,point[e].dist,point[e].kill);
    124     return 0;
    125 }
  • 相关阅读:
    【English】20190307
    【Teradata】四舍五入函数
    【Teradata】配置PE和AMP(congfig和reconfig工具、vprocmanager)
    【English】20190306
    【Teradata】数据库初始化(sysinit和dip工具)
    【Teradata】日期类型转换
    Optional常用操作
    Stream学习笔记
    拦截Restful API的三种方式
    maven之可执行jar包
  • 原文地址:https://www.cnblogs.com/cmyg/p/8727643.html
Copyright © 2020-2023  润新知