HDU1535——Invitation Cards(最短路径:SPAF算法+dijkstra算法)_weixin_30505485的博客-程序员宅基地

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+10],b[N+10],c[N+10],n,m,k;
 8 int dis[N+10],vis[N+10],first[N+10],next[N+10];
 9 void dijkstra(int pos,int *a,int *b,int *c)
10 {
11     int i,j,min;
12     for(i=1;i<=n;i++)
13         dis[i]=INT_MAX;
14     memset(vis,0,sizeof(vis));
15     vis[pos]=1;
16     i=first[pos];
17     while(i!=-1){
18         dis[b[i]]=c[i];
19         i=next[i];
20     }
21     dis[pos]=0;
22     for(i=1;i<n;i++){
23         min=INT_MAX;
24         for(j=1;j<=n;j++)
25             if(!vis[j]&&dis[j]<min){
26                 min=dis[j];
27                 pos=j;
28             }
29         vis[pos]=1;
30         j=first[pos];
31         while(j!=-1){
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,-1,sizeof(first));
42     for(i=1;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=1;i<=m;i++)
54             scanf("%d%d%d",&a[i],&b[i],&c[i]);
55         jiantu(a,b,c);
56         dijkstra(1,a,b,c);
57         sum=0;
58         for(i=2;i<=n;i++)
59             sum+=dis[i];
60         jiantu(b,a,c);
61         dijkstra(1,b,a,c);
62         for(i=2;i<=n;i++)
63             sum+=dis[i];
64         printf("%d\n",sum);
65     }
66     return 0;
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+10],edge2[MAXN+10];
14 int dis[MAXN+10],first[MAXN+10];
15 bool vis[MAXN+10];
16 int T,S,D,N,k,M;
17 void SPFA(int begin,struct e edge[])
18 {
19     for (int i=1; i<=N; i++)
20     {
21         dis[i]=INT_MAX;
22         vis[i]=0;
23     }
24     queue <int> Q;
25     Q.push(begin);
26     dis[begin]=0;
27     while (!Q.empty())
28     {
29         begin=Q.front();
30         Q.pop();
31         vis[begin]=0;
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]=1;
40                 }
41             }
42     }
43 }
44 void init(struct e edge[]) //first存各个顶点作为结点时的第一个下标
45 {
46     memset(first,0,sizeof(first));
47     first[edge[1].begin]=1;
48     for (int i=2;i<=M;i++)
49         if (edge[i-1].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=1; 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+1,edge1+M+1,cmp); //按begin顶点排序
71         sort(edge2+1,edge2+M+1,cmp);
72         init(edge1);
73         SPFA(1,edge1);
74         int cnt=0;
75         for (int i=1; i<=N; i++)
76             cnt+=dis[i];
77         init(edge2);
78         SPFA(1,edge2);
79         for (int i=1; i<=N; i++)
80             cnt+=dis[i];
81         printf("%d\n",cnt);
82     }
83     return 0;
84 }

转载于:https://www.cnblogs.com/Enumz/p/3860916.html

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_30505485/article/details/99024441

智能推荐

预编译指令集_近水楼台的博客-程序员宅基地

#define 定义一个预处理宏#undef 取消宏的定义#include 包含文件命令#include_next 与#include相似, 但它有着特殊的用途#if 编译预处理中的条件命令, 相当于C语法中的if语句#ifdef 判断某个宏是否被定义, 若已定义, 执行随后的语句#ifndef 与#ifdef相反, 判

vue自定义弹出框,点击全屏显示_艾小逗的博客-程序员宅基地

自定义弹出框title: 弹出框标题fullScreenIcon: { // 是否显示全屏按钮btnShow: { // 是否显示操作按钮closeBtn: { // 关闭按钮-文字submitBtn: { // 确定按钮-文字popWidth: { // 弹出层宽度使用方法<popContent v-if="dialogVisibleScore" :pop-width="1000" :full-screen-icon="true" :btn-show="fals

RabbitMQ 删除重新创建vhost,但总是Stopped的解决方法_rabbit mq vhost stop_普通网友的博客-程序员宅基地

RabbitMQ 删除重新创建vhost,但总是Stopped的解决方法.进入vhosts页面可以看到这里的state是stopped点击name,进入子页面如果此时state为 stopped, 会有 running 按钮.点击按钮后报错:找到上图圈住的路径,删除vhosts文件夹下的 随机字符串 文件夹,再次重新启动即可...._rabbit mq vhost stop

华为2道机试题(review)_192.168.1.100_weedge的博客-程序员宅基地

华为2道机试题:/**@date:2010/09/14@author:weedge@comment:1. 识别字符串中的整数并转换为数字形式问题描述: 识别输入字符串中所有的整数,统计整数个数并将这些字符串形式的整数转换为数字形式整数。要求实现函数: void_192.168.1.100

10、图像缩放_编写一个函数实现图像缩放功能,函数输入为原始图像和缩放系数,输出为缩放后图像数_MuMengSunny的博客-程序员宅基地

一、*resize()*函数实现图像的缩放语法格式:dst=cv2.resize(src,dsize,fx,fy)dst = cv2.resize(src,dsize,fx,fy)dst=cv2.resize(src,dsize,fx,fy)dsize是目标尺寸,先列后行;fx,fy分别代表水平方向与垂直方向放大的倍数dsize和 fx、fy设置一方即可,否则会出错,如:cv2.resize(src,(200,100))# 或者cv2.resize(src,None,fx=0.5,f_编写一个函数实现图像缩放功能,函数输入为原始图像和缩放系数,输出为缩放后图像数

GIT_学习日记_DAY01_进击的麻甩佬的博客-程序员宅基地

Git 基础1.直接记录快照,而非差异比较2.近乎所有操作都是本地执行3.时刻保持数据完整性4.多数操作仅添加数据5.文件的三种状态 已提交(committed),已修改(modified)和已暂存(staged) 基本的 Git 工作流程如下:1. 在工作目录中修改某些文件。2. 对修改后的文件进行快照,然后保存到暂存区域。3. 提交更新,将保存在暂存区域的文件快照永久转储到 Git ...

随便推点

Windows下安装nginx,nginx安装失败因为端口问题安装不了的解决方案_@shirley的博客-程序员宅基地

Windows下安装nginx一、什么是nginx二、为什么要使用nginx三、安装nginx1、下载nginx的安装文件2、安装1)正常情况下2)安装失败,解决方案首先我们来了解一下什么是nginx一、什么是nginx简单的来说:Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器其主要的优点就是:其特点是占有内存少,并发能力强,并且它的安装还非常的简洁二、为什么要使用nginx在传统的Web项目中,并发量小,用户使用的少。所以在低并发的情况下,用户

QT 实现 Toolbar 的全局颜色选择框 与按钮自定义演示选择_qt toolbar颜色_shiter的博客-程序员宅基地

文章大纲实现效果实现过程调整 工具栏设置工具栏按钮设置勾选框样式默认勾选设置信号函数其他调试参考参考文献实现效果初学QT 发现果真是强大的不行,原来我都是用MFC 虽然有异曲同工之妙 ,但是感觉跨平台的QT更加精髓一些,下面,我们来实现一个全局的自定义颜色选择工具栏,效果如下,主要由一组互斥的 CheckBox 和 一个单独的自定义 Qpushbutton 构成。实现过程调整 工具栏我们首先在主窗口布局的工具栏中 ,给工具栏增加我们自己写的,自定义选择框函数,并且由分隔符 隔开void_qt toolbar颜色

Java井字棋游戏__鲸落的博客-程序员宅基地

试着写了一个井字棋游戏,希望各位能给予一些宝贵的建议。一、棋盘类public class ChessBoard { private int number; // 设置棋子个数 public void setNumber(int number) { this.number = number; } // 获得棋子数 public int getNumber() { retur...

LocalDate类之某年某月的日历_localdate1月_lecherme的博客-程序员宅基地

LocalDate之某年某月的日历直接上代码:本人之前都是做投资的,虽然本科学的软件,但是没写过代码你懂的。2020年9月开始重新学java。在大佬门前班门弄斧,见笑了。。老年人再出发不容易。。轻拍。代码如下:import java.time.*;public class TestLocalDate { public static void main(String[] ab) { String[] week={"SUN","MON","TUE","WED","T_localdate1月

IT外包人力是否等同于低成本、低质量的人力资源?_ak619的博客-程序员宅基地

谈到这个话题,就要看甲方公司选择IT外包人力的目的是什么。如果是因为本身的开发团队缺少某项行业经验或技术的人才,需要从具备相应经验或资质的公司聘请技术人才作为技术领航人,在完成相应开发任务的同时,也培养自己的员工学习和掌握该技术,那么,这样的外包人力是当作专家对待,一定不是低成本、低质量的人力资源。如果是因为项目规模大,团队人力不足,需要补充开发或测试人力,此时,就要看你需要补充的哪种人力...

推荐文章

热门文章

相关标签