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算法+邻接表):

 #include<cstdio>
#include<cstring>
#include<climits>
#include<algorithm>
#define N 1000000
using namespace std;
int a[N+],b[N+],c[N+],n,m,k;
int dis[N+],vis[N+],first[N+],next[N+];
void dijkstra(int pos,int *a,int *b,int *c)
{
int i,j,min;
for(i=;i<=n;i++)
dis[i]=INT_MAX;
memset(vis,,sizeof(vis));
vis[pos]=;
i=first[pos];
while(i!=-){
dis[b[i]]=c[i];
i=next[i];
}
dis[pos]=;
for(i=;i<n;i++){
min=INT_MAX;
for(j=;j<=n;j++)
if(!vis[j]&&dis[j]<min){
min=dis[j];
pos=j;
}
vis[pos]=;
j=first[pos];
while(j!=-){
if(!vis[b[j]]&&dis[pos]+c[j]<dis[b[j]])
dis[b[j]]=dis[pos]+c[j];
j=next[j];
}
}
}
void jiantu(int *a,int *b,int *c)
{
int i;
memset(first,-,sizeof(first));
for(i=;i<=m;i++){
next[i]=first[a[i]];
first[a[i]]=i;
}
}
int main()
{
int T,i,sum;
scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&m);
for(i=;i<=m;i++)
scanf("%d%d%d",&a[i],&b[i],&c[i]);
jiantu(a,b,c);
dijkstra(,a,b,c);
sum=;
for(i=;i<=n;i++)
sum+=dis[i];
jiantu(b,a,c);
dijkstra(,b,a,c);
for(i=;i<=n;i++)
sum+=dis[i];
printf("%d\n",sum);
}
return ;
}

Code2(SPFA+优化):

 #include<stdio.h>
#include<limits.h>
#include<iostream>
#include<string>
#include<queue>
#define MAXN 1000000
using namespace std;
struct e
{
int begin;
int end;
int dis;
} edge1[MAXN+],edge2[MAXN+];
int dis[MAXN+],first[MAXN+];
bool vis[MAXN+];
int T,S,D,N,k,M;
void SPFA(int begin,struct e edge[])
{
for (int i=; i<=N; i++)
{
dis[i]=INT_MAX;
vis[i]=;
}
queue <int> Q;
Q.push(begin);
dis[begin]=;
while (!Q.empty())
{
begin=Q.front();
Q.pop();
vis[begin]=;
for (int i=first[begin]; edge[i].begin==begin; i++) //可以只遍历begin==edge[i].begin的edge
if (dis[edge[i].end]>dis[begin]+edge[i].dis)
{
dis[edge[i].end]=dis[begin]+edge[i].dis;
if (!vis[edge[i].end])
{
Q.push(edge[i].end);
vis[edge[i].end]=;
}
}
}
}
void init(struct e edge[]) //first存各个顶点作为结点时的第一个下标
{
memset(first,,sizeof(first));
first[edge[].begin]=;
for (int i=;i<=M;i++)
if (edge[i-].begin!=edge[i].begin) first[edge[i].begin]=i;
}
bool cmp(struct e a,struct e b)
{
return a.begin<b.begin;
}
int main()
{
int T;
cin>>T;
while (T--)
{
scanf("%d %d",&N,&M);
int x1,x2,x3;
for (int i=; i<=M; i++)
{
scanf("%d %d %d",&x1,&x2,&x3); //cin跑了2600ms scanf只要1300ms
//cin>>x1>>x2>>x3;
edge1[i].begin=x1,edge1[i].end=x2,edge1[i].dis=x3;
edge2[i].begin=x2,edge2[i].end=x1,edge2[i].dis=x3;
}
sort(edge1+,edge1+M+,cmp); //按begin顶点排序
sort(edge2+,edge2+M+,cmp);
init(edge1);
SPFA(,edge1);
int cnt=;
for (int i=; i<=N; i++)
cnt+=dis[i];
init(edge2);
SPFA(,edge2);
for (int i=; i<=N; i++)
cnt+=dis[i];
printf("%d\n",cnt);
}
return ;
}

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. php cURL library is not loaded

    问题: php 在命令行里面可以找到 curl 模块,但是用apache 没有找到 curl 模块. 表现内容为: extension_loaded('curl')cURL library is no ...

  2. 关于Socket编写简单聊天工具的总结(原创)

    这段时间再看socket编程,虽然现在是刚刚接触,但是还是忍不住想写一篇总结,来激励自己努力学习,写的不好的地方,还请大家指教啊! 下面针对一个简单的发送消息和文件的程序说说吧.   首先是服务器需要 ...

  3. chorme模拟微信浏览器

    chorme模拟微信浏览器 1.代码填入到图中2出 Mozilla/5.0 (Linux; Android 4.4.4; HM NOTE 1LTEW Build/KTU84P) AppleWebKit ...

  4. Kakfa揭秘 Day2 Kafka内核再揭秘

    Spark Streaming揭秘 Day33 Kafka内核再揭秘 优秀的框架会把引擎做到极致,Kafka就是这样,让我们再深入一下研究. 设计目标 kafka系统有着比较独特的的设计,包括5点: ...

  5. The Black Hole of Numbers (strtoint+inttostr+sort)

    For any 4-digit integer except the ones with all the digits being the same, if we sort the digits in ...

  6. iOS7.1Https企业证书发布方法

    openssl使用的是macos系统自带的版本,关键点是不同直接使用ios设备打开https的链接,需要将证书发到系统的mail里,安装到设备, 如果命令执行不成功,用sudo执行. 1.生成服务器的 ...

  7. ios NavBar+TarBar技巧

    NavBar+TarBar iphone开发 NavBar+TarBar 1  改变NavBar颜色:选中Navigation Bar 的Tint属性.选中颜色. 2  隐藏“back”按钮: sel ...

  8. Xcode常用设置

    1.设置主题和字体大小 2.设置显示代码行号

  9. C# Windows - RadioButton&CheckBox

    RadioButton和CheckBox控件与Button控件有相同的基类,但它们的外观和用法大不相同. RadioButton显示为一个标签,左边是一个圆点,该点可以是选中或未选中.用在给用户提供两 ...

  10. MYSQL系列1_MySQL的安装,可视化工具的使用,以及建库建表等

    大家都知道MYSQL是开源的数据库,现在MYSQL在企业中的使用也越来越多,本人之前用过SQL SERVER数据库,因业务需要和自己的兴趣想要学习MYSQL,对于MYSQL,本人还是新手,请大家多多指 ...