搜索
热搜: NOIP OIer 神牛
查看: 330|回复: 7

1383最短路径问题

[复制链接]

35

主题

54

帖子

4532

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
4532
发表于 2021-5-11 18:08:31 | 显示全部楼层 |阅读模式
建帖
回复

使用道具 举报

主题

帖子

0

积分

新手上路

Rank: 1

积分
0
发表于 2021-5-13 18:08:04 | 显示全部楼层
2021/5/13 18:08 已过
回复

使用道具 举报

主题

帖子

0

积分

新手上路

Rank: 1

积分
0
发表于 2021-5-13 18:41:29 | 显示全部楼层
本帖最后由 Hank 于 2021-5-29 10:26 编辑

First:读题
题目
一读题目,哇!最短路径模板题!
一看输入,唉?为啥给我一个表?
一扫输出,呼,这题没那么变态。
一盯范围,艹!这题我谢谢你啊!
那么这题的题目大致如下:
给你一个有向图和一个源点,让你求源点到每个其他点的最短路径
而且存在负边
还要用BF与LXX
(注:BF即Bellman-Ford算法,LXX即链式向前星)


Second:抽象
那接下来咋办呢?
鲁迅曾说:”输入要看懂,就算题目很简单,但输入是必须明白的。“

那就看呗,诶???
邻接矩阵???

老子要用LXX啊!
但不慌,诶我能转化
Wait,你为嘛用-表示无效啊!
我会跟负数混的!
那怎么办


Third:scanf
我们都知道scanf是有返回值的,能输就返回1,否则EOF
那......
  1. long long a;
  2.                         
  3.                         if(scanf("%lld", &a) == 1)
  4.                         {
  5.                                 aadd(i, j, a);
  6.                         }
  7.                         else
  8.                         {
  9.                                 continue;
  10.                         }
复制代码
不就得了
那咋转呢?
那这边建议您仔细看看上面
如果在第i行,第j列看到一个数a
就说明:存在一条从i至j的路径,其权重为a
由于是有向图,加一条就行了
ok,输入完了,注意long long


Fourth:BF
好了,现在就上模板吧:
模板啊,我是不会贴模板的
接着:
本题只差一个东西了:
CODE
  1. #include<cstring>
  2. #include<cmath>
  3. #include<cstdio>
  4. #include<cstdlib>
  5. #include<algorithm>
  6. #include<iomanip>
  7. #include<string>
  8. #include<queue>
  9. #include<iostream>
  10. using namespace std;

  11. #define MAX 10
  12. #define L int

  13. L n, s;
  14. L cnt, adj[MAX];
  15. L f[MAX];

  16. struct Edge
  17. {
  18.         L w;
  19.         L to;
  20.         L nxt;
  21. }edges[10];

  22. void add(L from, L to, L w)
  23. {
  24.         edges[cnt].to = to;
  25.         edges[cnt].w = w;
  26.         edges[cnt].to= adj[come];
  27.         adj[from] = cnt;
复制代码
FINISH!


^(* ̄(oo) ̄)^ 接下来是彩蛋:


Fifth:memsetwhy memset double 0x3f is so little?
memset[color=rgba(0, 0, 0, 0.75)] 是按字节填充
double[color=rgba(0, 0, 0, 0.75)] [color=rgba(0, 0, 0, 0.75)]占 8 字节
011111100111111001111110011111100111111001111110011111100111111
这是我们得到的数
而我们看这个数,它是几呢?
利用打印可得为0.747058808803558
so,还是用0x7f吧!

Sixth:SPFA
吗是SPFA?
SPFA = BF + 队列优化
那咋优化?
看这!
然后愉悦地code吧!
  1. #include<cstring>
  2. #include<cmath>
  3. #include<cstdio>
  4. #include<cstdlib>
  5. #include<algorithm>
  6. #include<iomanip>
  7. #include<string>
  8. #include<queue>
  9. #include<iostream>
  10. using namespace std;

  11. #define MAX 1011111111

  12. int n, m, s, t1;
  13. int cnt, adj[MAX];
  14. interesting f[MAX];

  15. struct Point
  16. {
  17.         int x;
  18.         int y;
  19. }p11[MAX];

  20. struct Edge
  21. {
  22.         int w;
  23.         int to;
  24.         int nxt;
  25. }edge[10010];

  26. void add(int from, int to, double w)
  27. {
  28.         cnt++;
  29.         edges[cnt].to = to;
  30.         edges[cnt].w = from;
  31.         edges[cnt].nxt = adj[from];
  32.         adj[from] = to;
  33. }

  34. void init_relax(int s)
  35. {
  36.         memset(f, 0x3f, sizeof(f));
  37.         f[s] = 0;
  38. }

  39. void relax(int from, int to, double w)
  40. {
  41.         if(f[to] > f[from] + w)
  42.         {
  43.                 f[to] = f[from] + w;
  44.         }
  45. }

  46. int main()
  47. {
  48.         cin >> n;
  49.        
  50.         for(int i = 1;i <= n;++i)
  51.         {
  52.                 cin >> p[i].x >> p[i].y;
  53.         }   
  54.        
  55.         cin >> m;
  56.        
  57.         for(int i = 1;i <= m;++i)
  58.         {
  59.                 int u, v;
  60.                
  61.                 scanf("%d %d", &u, &v);
  62.                
  63.                 double        w = sqrt((p[u].x - p[v].x) * (p[u].x - p[v].x) + (p[u].y - p[v].y) * (p[u].y - p[v].y));
  64.                
  65.                
  66.                 aadd(u, v, w);
  67.                 aadd(v, u, w);
  68.                
  69.         }
  70.        
  71.         cin >> s >> t;
  72.        
  73.         init_relax(s);
  74.        
  75.     for(int i = 1;i < n;++i)
  76.     {
  77.             for(int j = 1;j <= n;++j)
  78.             {
  79.                     for(int k = adj[j];k > 0;k = edges[k].nxt)
  80.                     {
  81.                             relax(j, edges[k].to, edges[k].w);
  82.                         }
  83.                 }
  84.         }
  85.        
  86.     printf("%.2lf", f[t]);
  87.    
  88.         return 0;
  89. }
复制代码
Seventh:dijkstra
  1. #include<cstring>
  2. #include<cmath>
  3. #include<cstdio>
  4. #include<cstdlib>
  5. #include<algorithm>
  6. #include<iomanip>
  7. #include<string>
  8. #include<queue>
  9. #include<iostream>
  10. using namespace std;

  11. #define MAX 10010

  12. struct Edge
  13. {
  14.         int nxt;
  15.         int to;
  16.         double w;
  17. }edges[MAX];

  18. struct Point
  19. {
  20.         int x;
  21.         int y;
  22. }p[MAX];


  23. int n, m, s, t;
  24. int cnt, adj[MAX];
  25. double f[MAX];
  26. bool vis[MAX], flag = true;

  27. void aadd(int from, int to, double w)
  28. {
  29.         cnt++;
  30.         edges[cnt].to = to;
  31.         edges[cnt].w = w;
  32.         edges[cnt].nxt = adj[from];
  33.         adj[from] = cnt;
  34. }

  35. void init_relax(int s)
  36. {
  37.         memset(f, 0x7f, sizeof(f));
  38.         f[s] = 0;
  39. }

  40. void relax(int from, int to, double w)
  41. {
  42.         if(f[to] > f[from] + w)
  43.         {
  44.                 f[to] = f[from] + w;
  45.         }
  46. }

  47. int dij(int s)
  48. {
  49.         init_relax(s);
  50.        
  51.         while(flag)
  52.         {
  53.                 flag = false;
  54.                 int i = 0;
  55.                
  56.                 for(int j = 1;j <= n;++j)
  57.                 {
  58.                         if(!vis[j])
  59.                         {
  60.                                 if(f[j] < f[i])
  61.                                 {
  62.                                         flag = true;
  63.                                         i = j;
  64.                                 }
  65.                         }
  66.                 }
  67.                
  68.                 vis[i] = true;
  69.        
  70.                 for(int k = adj[i];k;k = edges[k].nxt)
  71.                 {
  72.                         int l = edges[k].to;
  73.                
  74.                         if(!vis[l])
  75.                         {
  76.                                 relax(i, l, edges[k].w);
  77.                         }
  78.                 }
  79.         }
  80. }

  81. int main()
  82. {
  83.         cin >> n;
  84.        
  85.         for(int i = 1;i <= n;++i)
  86.         {
  87.                 cin >> p[i].x >> p[i].y;
  88.         }   
  89.        
  90.         cin >> m;
  91.        
  92.         for(int i = 1;i <= m;++i)
  93.         {
  94.                 int u, v;
  95.                
  96.                 scanf("%d %d", &u, &v);
  97.                
  98.                 double        w = sqrt((p[u].x - p[v].x) * (p[u].x - p[v].x) + (p[u].y - p[v].y) * (p[u].y - p[v].y));
  99.                
  100.                
  101.                 aadd(u, v, w);
  102.                 aadd(v, u, w);
  103.                
  104.         }
  105.        
  106.         cin >> s >> t;
  107.        
  108.         dij(s);
  109.        
  110.         printf("%.2lf", f[t]);
  111.        
  112.     return 0;
  113. }
复制代码
累了,直接来吧
不讲了
BDBL











彩蛋














                 haha
                                                                                                         
彩蛋上面有彩蛋(提示:我藏起来了,就在上面哦,只有在蓝色中才能发现 !)               




本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

主题

帖子

0

积分

新手上路

Rank: 1

积分
0
发表于 2021-5-14 19:48:33 | 显示全部楼层
2021/5/14 19/48 finish
回复

使用道具 举报

主题

帖子

0

积分

新手上路

Rank: 1

积分
0
发表于 2021-5-14 23:01:52 | 显示全部楼层
已改
00000000000000000000000000000000000
回复

使用道具 举报

主题

帖子

0

积分

新手上路

Rank: 1

积分
0
发表于 2021-5-15 18:40:45 | 显示全部楼层
彩蛋是啥??
回复

使用道具 举报

主题

帖子

0

积分

新手上路

Rank: 1

积分
0
发表于 2021-5-15 19:37:42 | 显示全部楼层
wq 发表于 2021-5-15 18:40
彩蛋是啥??

格局小了
回复

使用道具 举报

主题

帖子

0

积分

新手上路

Rank: 1

积分
0
发表于 2021-5-15 19:52:24 | 显示全部楼层
你是不是想高人一等:@
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

津ICP备19006949号-1 | 津公网安备12010102000465号

快速回复 返回顶部 返回列表