码迷,mamicode.com
首页 > 其他好文 > 详细

专题训练——[kuangbin带你飞]最短路练习

时间:2019-05-26 19:46:25      阅读:157      评论:0      收藏:0      [点我收藏+]

标签:队列   最大   icp   turn   告诉   aaa   close   level   type   

最短路练习

 

0. Til the Cows Come Home  POJ - 2387  

完美的模板题

技术图片
 1 //#include<Windows.h>
 2 #include<iostream>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<cstdio>
 6 #include<queue>
 7 using namespace std;
 8 const int MAX_V = 10005;
 9 const int MAX_E = 20010;
10 const int inf = 0x3f3f3f3f;
11 
12 struct ENode
13 {
14     int to;
15     int Next;
16     int w;
17 };
18 ENode Edegs[MAX_E];
19 int Head[MAX_V];
20 int Dis[MAX_V];
21 int tnt;
22 void Add_ENode(int u, int v, int w)
23 {
24     ++tnt;
25     Edegs[tnt].to = v;
26     Edegs[tnt].w = w;
27     Edegs[tnt].Next = Head[u];
28     Head[u] = tnt;
29     ++tnt;
30     Edegs[tnt].to = u;
31     Edegs[tnt].w = w;
32     Edegs[tnt].Next = Head[v];
33     Head[v] = tnt;
34 }
35 struct cmpx
36 {
37     bool operator () (int &a, int &b) const
38     {
39         return Dis[a] - Dis[b] > 0;
40     }
41 };
42 
43 void Dijkstra(int x)
44 {
45     priority_queue<int, vector<int>, cmpx> q;
46     memset(Dis, inf, sizeof(Dis));
47     Dis[x] = 0;
48     q.push(x);
49     while (!q.empty())
50     {
51         int u = q.top();
52         q.pop();
53         for (int k = Head[u]; k != -1; k= Edegs[k].Next)
54         {
55             int v = Edegs[k].to;
56             if (Dis[v] > Dis[u] + Edegs[k].w)
57             {
58                 Dis[v] = Dis[u] + Edegs[k].w;
59                 q.push(v);
60             }
61         }
62     }
63 }
64 
65 int main()
66 {
67     int t, n;
68     cin >> t >> n;
69     tnt = -1;
70     int a, b, w;
71     memset(Head, -1, sizeof(Head));
72     for (int i = 0; i < t; i++)
73     {
74         cin >> a >> b >> w;
75         Add_ENode(a, b, w);
76     }
77     Dijkstra(1);
78     cout << Dis[n] << endl;
79 //    system("pause");
80     return 0;
81 }
View Code

 

1. Frogger POJ - 2253  

青蛙和石头。在池塘里有2只青蛙和n块石头,石头之间有一定距离,现在一只(腿短的)青蛙想要去找另一只青蛙yuehui;给出n块石头的坐标,1号为男主青蛙所在的石头,二号为目标石头,问它在所有可行路径中需要的单次最短跳跃距离是多少?

技术图片
 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<cstdio>
 5 #include<queue>
 6 #include<cmath>
 7 using namespace std;
 8 const int MAX_V= 210;
 9 const double inf= 99999999999999999.0;
10 typedef pair<double, double> _pair;
11 _pair rock[MAX_V];
12 double get_dis(_pair a, _pair b)
13 {
14     return sqrt(((a.first- b.first)* (a.first- b.first) )+ ((a.second- b.second)* (a.second- b.second) ) );
15 }
16 double Dis[MAX_V];
17 struct cmpx
18 {
19     bool operator() (int &a, int &b) const
20     {
21         return Dis[a]- Dis[b]> 0; 
22     }
23 };
24 int Front[MAX_V];
25 void Dijkstra(int n)
26 {
27     priority_queue<int, vector<int>, cmpx> q;
28     fill(Dis, Dis+ n+ 1, inf);
29     //for(int i= 1; i<= n; i ++) printf("%f\n", Dis[2]);
30     Dis[1]= 0;
31     Front[1]= -1;
32     q.push(1);
33     while (! q.empty() )
34     {
35         int u= q.top();
36         q.pop();
37         for (int i= 2; i<= n; i ++)
38         {
39             if (i== u) continue;
40             double detmp= get_dis(rock[u], rock[i]);
41             //printf("%f---%f---%f\n", Dis[u], detmp, Dis[i]);
42             if (Dis[i]> Dis[u]&& Dis[i]> detmp)
43             {
44                 Dis[i]= max(Dis[u], detmp);
45                 Front[i]= u;
46                 q.push(i);
47             }
48             //printf("%f\n", Dis[i]);
49         }
50     }
51 }
52 int main()
53 {
54     int n;
55     int t= 0;
56     while (cin >> n)
57     {
58         ++ t;
59         if (n== 0) break;
60         for (int i= 1; i<= n; i ++)
61         {
62             cin >> rock[i].first >> rock[i].second;
63         }
64         //for(int i= 2; i<= n; i ++) printf("%f\n", get_dis(rock[1], rock[i]));
65         Dijkstra(n);
66         printf("Scenario #%d\n",t);
67         printf("Frog Distance = %.3f\n\n", Dis[2]);
68         double ans= -1.0;
69         /*for (int c= n; c!= 1; c= Front[c])
70         {
71             double cnp= get_dis(rock[c], rock[Front[c]]);
72             ans= max(ans, cnp);
73         }
74         printf("Frog Distance = %.3f\n\n", ans);*/
75     }
76     return 0;
77 }
View Code

 

2. Heavy Transportation POJ - 1797  

城市中有N个路口,M个街道,每条街道都有最大承重限制;现在我们想要驾车从1号路口到N号路口,那么运输车所允许的最大重量是多少?

 

3. Travel (The 2019 ACM-ICPC China Shannxi Provincial Programming Contest M)  /**计蒜客复现赛:点这里*/

星系中有n 个星球,编号从1 到N。星球之间有M个隧道相连,每个隧道都有一个长度。你有一个航天器,航天器有两个属性:传输距离d 和传输次数e 。航天器只能通过短于或等于其传输距离的通道;如果传输次数耗尽,则无法再使用航天器。航天器具有等级,lv0的航天器d 和e 都等于0,你可以给你的航天器升级,每次升级都会消耗c 点花费,给你的航天器提升dx和 ex点属性。现在,告诉你n,m,m条通道的信息,还有给你的航天器升级时的c,dx,ex。

Q: 你能求出从1 到N 的最小花费吗?

A: 把原本记录到达此点最短距离的Dis[] 变成 记录到达此点所需要飞行器最低等级的Dis_Level[],这样剩下的就是普通的Dijkstra了。

技术图片
 1 #include<algorithm>
 2 #include<cstring>
 3 #include<cstdio>
 4 #include<queue>
 5 using namespace std;
 6 const int MAX_V= 100010;
 7 const int MAX_E= 400010;
 8 const int inf= 0x3f3f3f3f;
 9 
10 struct ENode
11 {
12     int to;
13     int w;
14     int Next;
15 };
16 ENode edegs[MAX_E];
17 int Head[MAX_V], tnt;
18 void Add_ENode(int a, int b, int w)
19 {
20     edegs[++ tnt].to= b;
21     edegs[tnt].w= w;
22     edegs[tnt].Next= Head[a];
23     Head[a]= tnt;
24     edegs[++ tnt].to= a;
25     edegs[tnt].w= w;
26     edegs[tnt].Next= Head[b];
27     Head[b]= tnt;
28 }
29 
30 int Dis_Level[MAX_V];  //到每个点,所需要的飞船最小等级;
31 int deep[MAX_V];  //每个点bfs 的深度;
32 struct cmpx
33 {
34     bool operator() (int &a, int &b) const
35     {
36         return Dis_Level[a]- Dis_Level[b]> 0;
37     }
38 };
39 void Dijkstra(int x, int _dis, int _cost)
40 {
41     /*x为起点, _dis是每次升级提升的传送距离, _cost是升级提升的传送次数;*/
42     memset(Dis_Level, inf, sizeof(Dis_Level));
43     memset(deep, inf, sizeof(deep));
44     priority_queue<int, vector<int>, cmpx> q;
45     Dis_Level[x]= 0; //起点的飞行器等级为0;
46     deep[x]= 0;  //起点深度为0;
47     q.push(x);
48     while (! q.empty())
49     {
50         int u= q.top();
51         q.pop();
52         for (int k= Head[u]; k!= -1; k= edegs[k].Next)
53         {
54             int v= edegs[k].to;
55             int lev_tmp= Dis_Level[u];
56             while (lev_tmp* _dis< edegs[k].w|| lev_tmp* _cost< deep[u]+ 1)
57             {
58                 /*若当前的飞行器等级不能穿越此隧道,或传送次数已用完,则升级飞行器一次;*/
59                 lev_tmp ++;
60             }
61             if (lev_tmp< Dis_Level[v])
62             {
63                 /*如果此时的飞行器等级小与之前到达点v 的飞行器等级,则更新Dis_Level[v]*/
64                 Dis_Level[v]= lev_tmp;
65                 deep[v]= deep[u]+ 1; //深度也要 +1;
66                 q.push(v); //加入队列;
67             }
68         }
69     }
70 }
71 void into()
72 {
73     memset(Head, -1, sizeof(Head));
74     tnt= -1;
75 }
76 
77 int main()
78 {
79     int n, m;
80     int c, d, e;
81     int a, b ,w;
82     while (~ scanf("%d %d", &n, &m))
83     {
84         scanf("%d %d %d", &c, &d, &e);
85         into();
86         for (int i= 0;i< m;i ++)
87         {
88             scanf("%d %d %d", &a, &b, &w);
89             Add_ENode(a, b, w);
90         }
91         Dijkstra(1, d, e);
92         if (Dis_Level[n]== inf) printf("-1\n");
93         else printf("%lld\n", (long long)Dis_Level[n]* c);
94     }
95     return 0;
96 }
View Code

 

专题训练——[kuangbin带你飞]最短路练习

标签:队列   最大   icp   turn   告诉   aaa   close   level   type   

原文地址:https://www.cnblogs.com/Amaris-diana/p/10778340.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!