最短路 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\n",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\n",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("\n%ld %ld %ld\n",point[e].count,point[e].dist,point[e].kill);
124     return 0;
125 }

 

转载于:https://www.cnblogs.com/cmyg/p/8727643.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值