Invitation Cards

Description
In the age of television, not many people attend theater performances. Antique Comedians of Malidinesia are aware of this fact. They want to propagate theater and, most of all, Antique Comedies. They have printed invitation cards with all the necessary information and with the programme. A lot of students were hired to distribute these invitations among the people. Each student volunteer has assigned exactly one bus stop and he or she stays there the whole day and gives invitation to people travelling by bus. A special course was taken where students learned how to influence people and what is the difference between influencing and robbery.
The transport system is very special: all lines are unidirectional and connect exactly two stops. Buses leave the originating stop with passangers each half an hour. After reaching the destination stop they return empty to the originating stop, where they wait until the next full half an hour, e.g. X:00 or X:30, where 'X' denotes the hour. The fee for transport between two stops is given by special tables and is payable on the spot. The lines are planned in such a way, that each round trip (i.e. a journey starting and finishing at the same stop) passes through a Central Checkpoint Stop (CCS) where each passenger has to pass a thorough check including body scan.
All the ACM student members leave the CCS each morning. Each volunteer is to move to one predetermined stop to invite passengers. There are as many volunteers as stops. At the end of the day, all students travel back to CCS. You are to write a computer program that helps ACM to minimize the amount of money to pay every day for the transport of their employees.
Input
The input consists of N cases. The first line of the input contains only positive integer N. Then follow the cases. Each case begins with a line containing exactly two integers P and Q, 1 <= P,Q <= 1000000. P is the number of stops including CCS and Q the number of bus lines. Then there are Q lines, each describing one bus line. Each of the lines contains exactly three numbers - the originating stop, the destination stop and the price. The CCS is designated by number 1. Prices are positive integers the sum of which is smaller than 1000000000. You can also assume it is always possible to get from any stop to any other stop.
Output
For each case, print one line containing the minimum amount of money to be paid each day by ACM for the travel costs of its volunteers.
Sample Input
2
2 2
1 2 13
2 1 33
4 6
1 2 10
2 1 60
1 3 20
3 4 10
2 4 5
4 1 50
Sample Output
46
210

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

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

解题思路:

    求两边最短路,第二遍把边反向。求总和就行了。

    PS:这个题数据比较多和大,使用dijkstra算法和SPFA算法会超时,需要优化。具体细节看备注。

Code1(dijkstra算法+邻接表):

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<climits>
  4. #include<algorithm>
  5. #define N 1000000
  6. using namespace std;
  7. int a[N+],b[N+],c[N+],n,m,k;
  8. int dis[N+],vis[N+],first[N+],next[N+];
  9. void dijkstra(int pos,int *a,int *b,int *c)
  10. {
  11. int i,j,min;
  12. for(i=;i<=n;i++)
  13. dis[i]=INT_MAX;
  14. memset(vis,,sizeof(vis));
  15. vis[pos]=;
  16. i=first[pos];
  17. while(i!=-){
  18. dis[b[i]]=c[i];
  19. i=next[i];
  20. }
  21. dis[pos]=;
  22. for(i=;i<n;i++){
  23. min=INT_MAX;
  24. for(j=;j<=n;j++)
  25. if(!vis[j]&&dis[j]<min){
  26. min=dis[j];
  27. pos=j;
  28. }
  29. vis[pos]=;
  30. j=first[pos];
  31. while(j!=-){
  32. if(!vis[b[j]]&&dis[pos]+c[j]<dis[b[j]])
  33. dis[b[j]]=dis[pos]+c[j];
  34. j=next[j];
  35. }
  36. }
  37. }
  38. void jiantu(int *a,int *b,int *c)
  39. {
  40. int i;
  41. memset(first,-,sizeof(first));
  42. for(i=;i<=m;i++){
  43. next[i]=first[a[i]];
  44. first[a[i]]=i;
  45. }
  46. }
  47. int main()
  48. {
  49. int T,i,sum;
  50. scanf("%d",&T);
  51. while(T--){
  52. scanf("%d%d",&n,&m);
  53. for(i=;i<=m;i++)
  54. scanf("%d%d%d",&a[i],&b[i],&c[i]);
  55. jiantu(a,b,c);
  56. dijkstra(,a,b,c);
  57. sum=;
  58. for(i=;i<=n;i++)
  59. sum+=dis[i];
  60. jiantu(b,a,c);
  61. dijkstra(,b,a,c);
  62. for(i=;i<=n;i++)
  63. sum+=dis[i];
  64. printf("%d\n",sum);
  65. }
  66. return ;
  67. }

Code2(SPFA+优化):

  1. #include<stdio.h>
  2. #include<limits.h>
  3. #include<iostream>
  4. #include<string>
  5. #include<queue>
  6. #define MAXN 1000000
  7. using namespace std;
  8. struct e
  9. {
  10. int begin;
  11. int end;
  12. int dis;
  13. } edge1[MAXN+],edge2[MAXN+];
  14. int dis[MAXN+],first[MAXN+];
  15. bool vis[MAXN+];
  16. int T,S,D,N,k,M;
  17. void SPFA(int begin,struct e edge[])
  18. {
  19. for (int i=; i<=N; i++)
  20. {
  21. dis[i]=INT_MAX;
  22. vis[i]=;
  23. }
  24. queue <int> Q;
  25. Q.push(begin);
  26. dis[begin]=;
  27. while (!Q.empty())
  28. {
  29. begin=Q.front();
  30. Q.pop();
  31. vis[begin]=;
  32. for (int i=first[begin]; edge[i].begin==begin; i++) //可以只遍历begin==edge[i].begin的edge
  33. if (dis[edge[i].end]>dis[begin]+edge[i].dis)
  34. {
  35. dis[edge[i].end]=dis[begin]+edge[i].dis;
  36. if (!vis[edge[i].end])
  37. {
  38. Q.push(edge[i].end);
  39. vis[edge[i].end]=;
  40. }
  41. }
  42. }
  43. }
  44. void init(struct e edge[]) //first存各个顶点作为结点时的第一个下标
  45. {
  46. memset(first,,sizeof(first));
  47. first[edge[].begin]=;
  48. for (int i=;i<=M;i++)
  49. if (edge[i-].begin!=edge[i].begin) first[edge[i].begin]=i;
  50. }
  51. bool cmp(struct e a,struct e b)
  52. {
  53. return a.begin<b.begin;
  54. }
  55. int main()
  56. {
  57. int T;
  58. cin>>T;
  59. while (T--)
  60. {
  61. scanf("%d %d",&N,&M);
  62. int x1,x2,x3;
  63. for (int i=; i<=M; i++)
  64. {
  65. scanf("%d %d %d",&x1,&x2,&x3); //cin跑了2600ms scanf只要1300ms
  66. //cin>>x1>>x2>>x3;
  67. edge1[i].begin=x1,edge1[i].end=x2,edge1[i].dis=x3;
  68. edge2[i].begin=x2,edge2[i].end=x1,edge2[i].dis=x3;
  69. }
  70. sort(edge1+,edge1+M+,cmp); //按begin顶点排序
  71. sort(edge2+,edge2+M+,cmp);
  72. init(edge1);
  73. SPFA(,edge1);
  74. int cnt=;
  75. for (int i=; i<=N; i++)
  76. cnt+=dis[i];
  77. init(edge2);
  78. SPFA(,edge2);
  79. for (int i=; i<=N; i++)
  80. cnt+=dis[i];
  81. printf("%d\n",cnt);
  82. }
  83. return ;
  84. }

HDU1535——Invitation Cards(最短路径:SPAF算法+dijkstra算法)的更多相关文章

  1. 最短路径算法-Dijkstra算法的应用之单词转换(词梯问题)(转)

    一,问题描述 在英文单词表中,有一些单词非常相似,它们可以通过只变换一个字符而得到另一个单词.比如:hive-->five:wine-->line:line-->nine:nine- ...

  2. 最短路径问题的Dijkstra算法

      问题 最短路径问题的Dijkstra算法 是由荷兰计算机科学家艾兹赫尔·戴克斯特拉提出.迪科斯彻算法使用了广度优先搜索解决非负权有向图的单源最短路径问题,算法终于得到一个最短路径树>    ...

  3. 单源最短路径问题2 (Dijkstra算法)

    用邻接矩阵 /* 单源最短路径问题2 (Dijkstra算法) 样例: 5 7 0 1 3 0 3 7 1 2 4 1 3 2 2 3 5 2 4 6 3 4 4 输出: [0, 3, 7, 5, 9 ...

  4. 图论(四)------非负权有向图的单源最短路径问题,Dijkstra算法

    Dijkstra算法解决了有向图G=(V,E)上带权的单源最短路径问题,但要求所有边的权值非负. Dijkstra算法是贪婪算法的一个很好的例子.设置一顶点集合S,从源点s到集合中的顶点的最终最短路径 ...

  5. 单源最短路径—Bellman-Ford和Dijkstra算法

    Bellman-Ford算法:通过对边进行松弛操作来渐近地降低从源结点s到每个结点v的最短路径的估计值v.d,直到该估计值与实际的最短路径权重相同时为止.该算法主要是基于下面的定理: 设G=(V,E) ...

  6. 《算法导论》读书笔记之图论算法—Dijkstra 算法求最短路径

    自从打ACM以来也算是用Dijkstra算法来求最短路径了好久,现在就写一篇博客来介绍一下这个算法吧 :) Dijkstra(迪杰斯特拉)算法是典型的最短路径路由算法,用于计算一个节点到其他所有节点的 ...

  7. 最短路径算法——Dijkstra算法

    在路由选择算法中都要用到求最短路径算法.最出名的求最短路径算法有两个,即Bellman-Ford算法和Dijkstra算法.这两种算法的思路不同,但得出的结果是相同的. 下面只介绍Dijkstra算法 ...

  8. C++编程练习(11)----“图的最短路径问题“(Dijkstra算法、Floyd算法)

    1.Dijkstra算法 求一个顶点到其它所有顶点的最短路径,是一种按路径长度递增的次序产生最短路径的算法. 算法思想: 按路径长度递增次序产生算法: 把顶点集合V分成两组: (1)S:已求出的顶点的 ...

  9. 单源最短路径问题之dijkstra算法

    欢迎探讨,如有错误敬请指正 如需转载,请注明出处 http://www.cnblogs.com/nullzx/ 1. 算法的原理 以源点开始,以源点相连的顶点作为向外延伸的顶点,在所有这些向外延伸的顶 ...

随机推荐

  1. MySQ binlog三种模式

    MySQ binlog三种模式及设置方法 1.1 Row Level  行模式 日志中会记录每一行数据被修改的形式,然后在slave端再对相同的数据进行修改 优点:在row level模式下,bin- ...

  2. Linux防火墙基本知识

    一.防火墙的分类 (一).包过滤防火墙. 数据包过滤(packet Filtering)技术是在网络层对数据包进行选择,选择的依据是系统内设置的过滤逻辑,称为访问控制表(access control ...

  3. Brackets - 又一款牛x的WEB开发编辑器

    Brackets官网下载: http://brackets.io/ Adobe Brackets是由Adobe主导开发一款主打web开发的编辑器. 是继TextMate,Sublime Text这两个 ...

  4. ios客户端base64上传图片到java服务器遇到的问题

    由于base64位包含了“+”和“\”两个特殊符号,导致ios编码后上传图片到服务器,服务器解码以后的值会不一致,导致图片损坏. 解决办法:重写Base64类,用“(”和“)”替换“+”和“\”两个特 ...

  5. Angular之【form提交问题】

    前端页面是这样: <form class="form-horizontal" role="form" name="LoginForm" ...

  6. [ Windows] [ OS ] [ Remote Desktop ] 開啟同一個帳號同時2的連線RDP的方式

    感謝同事 Allen 的Support :) 執行>gpedit.msc 電腦設定>Windows元件>遠端桌面服務>遠端桌面工作階段主機>連線>限制遠端桌面服務的 ...

  7. python学习之html从0开始(二)

    <!DOCTYPE html> <html> <head> <meta http-equiv="content-type" content ...

  8. php 字母大小写转换的函数

    分享下,在php编程中,将字母大小写进行转换的常用函数. 1.将字符串转换成小写strtolower(): 该函数将传入的字符串参数所有的字符都转换成小写,并以小定形式放回这个字符串 2.将字符转成大 ...

  9. web.xml中JSP配置及 EL表达式

    web.xml 中JSP配置.servlet配置 及 EL表达式 [摘要] servlet 基本配置 <servlet> <servlet-name>LoginServlet& ...

  10. C#网络编程简单实现通信小例子-2

    1.主界面  2.源代码                                                         Client public partial class For ...