题意:

有编号1~P的站点, 有Q条公交车路线,公交车路线只从一个起点站直接到达终点站,是单向的,每条路线有它自己的车费。

有P个人早上从1出发,他们要到达每一个公交站点, 然后到了晚上再返回点1。 求所有人来回的最小费用之和。

思路:

1.两次SPFA,也就是巧妙的将路线进行了翻转。

code 1:(数据较大,不能用二维数组,用的邻接表)

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <algorithm>
  4. #include <queue>
  5. using namespace std;
  6. #define MAXN 1000000
  7. #define INF 0x3f3f3f3f
  8. struct node
  9. {
  10. int now,to,w;
  11. }edge[MAXN];//记录每条边的信息,起始点,终止点,权值
  12. int first[MAXN],next[MAXN];
  13. int dis[MAXN],vis[MAXN];
  14. int n,m;
  15. void turnup()//反转图
  16. {
  17. int i,k;
  18. for(i = ; i<=m; i++)
  19. first[i] = next[i] = -;
  20. for(i = ; i<m; i++)
  21. {
  22. k= edge[i].to;
  23. next[i] = first[k];
  24. first[k] = i;
  25. }
  26. }
  27. void SPFA2(int start)
  28. {
  29. int i;
  30. for(i = ; i<=n; i++)
  31. dis[i] = INF;
  32. dis[start] = ;
  33. memset(vis,,sizeof(vis));
  34. queue<int> Q;
  35. Q.push(start);
  36. while(!Q.empty())
  37. {
  38. start = Q.front();
  39. Q.pop();
  40. vis[start] = ;
  41. i = first[start];
  42. while()
  43. {
  44. int to = edge[i].now;
  45. if(dis[to]>dis[start]+edge[i].w)
  46. {
  47. dis[to]=dis[start]+edge[i].w;
  48. if(!vis[to])
  49. {
  50. vis[to] = ;
  51. Q.push(to);
  52. }
  53. }
  54. i = next[i];
  55. if(i==-)
  56. break;
  57. }
  58. }
  59. return;
  60. }
  61. void SPFA1(int start)
  62. {
  63. int i;
  64. for(i = ; i<=n; i++)
  65. dis[i] = INF;
  66. dis[start] = ;
  67. memset(vis,,sizeof(vis));
  68. queue<int> Q;
  69. Q.push(start);
  70. while(!Q.empty())
  71. {
  72. start = Q.front();
  73. Q.pop();
  74. vis[start] = ;
  75. i=first[start];
  76. while()
  77. {
  78. int to = edge[i].to;
  79. if(dis[to]>dis[start]+edge[i].w)
  80. {
  81. dis[to]=dis[start]+edge[i].w;
  82. if(!vis[to])
  83. {
  84. vis[to] = ;
  85. Q.push(to);
  86. }
  87. }
  88. i = next[i];
  89. if(i==-)
  90. break;
  91. }
  92. }
  93. return;
  94. }
  95. int main()
  96. {
  97. int t,sum,i;
  98. scanf("%d",&t);
  99. while(t--)
  100. {
  101. sum = ;
  102. scanf("%d%d",&n,&m);
  103. for(i=; i<m; i++)
  104. first[i]=next[i]=-;
  105. for(i=; i<m; i++)
  106. {
  107. scanf("%d%d%d",&edge[i].now,&edge[i].to,&edge[i].w);
  108. next[i]=first[edge[i].now];
  109. first[edge[i].now]=i;
  110. }
  111. SPFA1();
  112. for(i = ; i<=n; i++)
  113. sum+=dis[i];
  114. turnup();
  115. SPFA2();
  116. for(i = ; i<=n; i++)
  117. sum+=dis[i];
  118. printf("%d\n",sum);
  119. }
  120. return ;
  121. }

这里SPFA 可以优化,关于SPFA的优化:

SLF:Small Label First 策略。

  实现方法是,设队首元素为 i,队列中要加入节点 j,在 dj<=di 时加到队首而不是队尾,否则和普通的 SPFA 一样加到队尾。

LLL:Large Label Last 策略。

  实现方法是,设队列 Q 中的队首元素为 i,距离标号的平均值为 avg(d),每次出队时,若 di>avg(d),把 i 移到队列末尾,如此反复,直到找到一个 i 使 ,di<=avg(d)将其出队。

HDU 1535 Invitation Cards(SPFA,及其优化)的更多相关文章

  1. hdu 1535 Invitation Cards(SPFA)

    Invitation Cards Time Limit : 10000/5000ms (Java/Other)   Memory Limit : 65536/65536K (Java/Other) T ...

  2. [HDU 1535]Invitation Cards[SPFA反向思维]

    题意: (欧洲人自己写的题面就是不一样啊...各种吐槽...果断还是看晕了) 有向图, 有个源叫CCS, 求从CCS到其他所有点的最短路之和, 以及从其他所有点到CCS的最短路之和. 思路: 返回的时 ...

  3. HDU 1535 Invitation Cards(最短路 spfa)

    题目链接: 传送门 Invitation Cards Time Limit: 5000MS     Memory Limit: 32768 K Description In the age of te ...

  4. HDU - 1535 Invitation Cards 前向星SPFA

    Invitation Cards In the age of television, not many people attend theater performances. Antique Come ...

  5. hdu 1535 Invitation Cards(spfa)

    Invitation Cards Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others ...

  6. HDU 1535 Invitation Cards(逆向思维+邻接表+优先队列的Dijkstra算法)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1535 Problem Description In the age of television, n ...

  7. HDU 1535 Invitation Cards (POJ 1511)

    两次SPFA. 求 来 和 回 的最短路之和. 用Dijkstra+邻接矩阵确实好写+方便交换.可是这个有1000000个点.矩阵开不了. d1[]为 1~N 的最短路. 将全部边的 邻点 交换. d ...

  8. HDU 1535 Invitation Cards (最短路)

    题目链接 Problem Description In the age of television, not many people attend theater performances. Anti ...

  9. hdu 1535 Invitation Cards (最短路径)

    Invitation Cards Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others ...

随机推荐

  1. C# 使用IENUMERABLE,YIELD

    C# 使用IENUMERABLE,YIELD 前言 在上篇文章中我得出结论,遍历迭代器修改迭代器中项目的值未生效,是因为使用了yield return,并且每次遍历迭代器都执行返回迭代器的方法.这篇文 ...

  2. Beginning MyBatis 3 Part 2 : How to Handle One-to-Many and One-to-One Selects

    One of the latest MyBatis feature is the ability to use Annotations or XML to do One-to-One or One-t ...

  3. keepalived 结合mysql 自动切换

    启动keepalived:/usr/local/sbin/keepalived -D -d -S 0 master ip:192.168.32.6 master:/root/sbin# cat /et ...

  4. ArrayList内元素按照字典排序

    package day08; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; ...

  5. java--函数练习

    /* 1,定义一个功能,用于打印矩形 1,定义一个打印九九乘法表功能的函数 */ class FunctionTest { public static void main(String[] args) ...

  6. The type MultipartEntity is deprecated

    在HttpCient4.3之前上传文件主要使用MultipartEntity这个类,但如今这个类已经不在推荐使用了(过时了).随之替代它的类是MultipartEntityBuilder.关于Mult ...

  7. 前端面试题整理(css)

    1.介绍所知道的CSS hack技巧(如:_, *, +, \9, !important 之类). CSS hack的原理: 由于不同的浏览器和浏览器各版本对CSS的支持及解析结果不一样,以及CSS优 ...

  8. php连接oracle及简单操作

    使你的php支持oracle,按照以下步骤即可: 1.安装php环境,找一下appserv或者xampp,一键安装,很方便 2.把php的ext目录下的php_oci8.dll拷到system32目录 ...

  9. 二维码闪电登录流程详解,附demo(2/2)

    上篇文章,我们重点介绍了一下二维码登录的流程,以及每个“角色”要做的事情,下面我们重点分析TV角色所做的工作. TV主要完成二维码图片显示,以及websocket请求.下面重点说一下这两点. 1. B ...

  10. 程序实践系列(七)C++概述

    理论练习题 C++语言与C语言的本质区别是什么? [參考答案]:C++与C语言的本质区别就在于C++是面向对象的.而C语言是面向过程的. 面向过程的程序设计方法与面向对象的程序设计方法在对待数据和函数 ...