C++ P1685 游览

2024-08-23 16:18
文章标签 c++ 游览 p1685

本文主要是介绍C++ P1685 游览,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

题目描述

顺利通过了黄药师的考验,下面就可以尽情游览桃花岛了!

你要从桃花岛的西头开始一直玩到东头,然后在东头的码头离开。可是当你游玩了一次后,发现桃花岛的景色实在是非常的美丽!!!于是你还想乘船从桃花岛东头的码头回到西头,再玩一遍,但是桃花岛有个规矩:你可以游览无数遍,但是每次游玩的路线不能完全一样。

我们把桃花岛抽象成了一个图,共n个点代表路的相交处,m条边表示路,边是有向的(只能按照边的方向行走),且可能有连接相同两点的边。输入保证这个图没有环,而且从西头到东头至少存在一条路线。两条路线被认为是不同的当且仅当它们所经过的路不完全相同。

你的任务是:把所有不同的路线游览完一共要花多少时间?

输入输出格式

输入格式:

第1行为5个整数:n、m、s、t、t0,分别表示点数,边数,岛西头的编号,岛东头的编号(编号是从1到n)和你乘船从岛东头到西头一次的时间。

以下m行,每行3个整数:x、y、t,表示从点x到点y有一条行走耗时为t的路。

每一行的多个数据之间用一个空格隔开,且:2<=n<=10000; 1<=m<=50000;t<=10000;t0<=10000

输出格式:

假设总耗时为total,则输出total mod 10000的值(total对10000取余)。

输入输出样例

输入样例:

3 4 1 3 7
1 2 5
2 3 7
2 3 10
1 3 15

输出样例:

56

说明

【样例说明】

共有3条路径可以从点1到点3,分别是1-2-3,1-2-3,1-3。

时间计算为:

(5+7)+7 +(5+10)+7 +(15)=56

题目链接:https://www.luogu.org/problemnew/show/P1685


个人思路:

  • 通过题意,很显然是DAG.通过DAG的定义,我们可以考虑到:DAG存在无后效性,也就是我们可以使用拓扑排序。
  • 由于要计算到达终点的所有可能路线的权值总和+可能的路线数*t0(t0的含义从题意可得),那么我们从"可能的路线数"就可以考虑(联想)到一个推论(DAG上的推论1)了。从推论1我们可以知道某条边可能被经过的数量,那么对于某个点v,从其他点连接v点的边集的被经过的数量的和即是点v可能被经过的数量。
  • 通过点v可能被经过的数量即可推论出结果。

#include<cstdio>
#include<iostream>
#include<queue>
#define mod 10000
using namespace std;
int s,t,t0,cnt=0,head[10005],rd[10005];//t,t0:岛西头的编号,岛东头的编号(编号是从1到n)和你乘船从岛东头到西头一次的时间
long long total=0,dp[10005];//dp数组 用于存储到达某个点的最大时间
struct Edge{int v,w,nxt;
}e[50005];
void addEdge(int u,int v,int w){e[++cnt].v=v;e[cnt].w=w;e[cnt].nxt=head[u];head[u]=cnt;
}
long long cntA[10005];//用于存储某个点可能被经过的数量
void topoSort(){queue<int> q;q.push(s);cntA[s]=1;while(!q.empty()){int nowValue=q.front();q.pop();for(int i=head[nowValue];i;i=e[i].nxt){int nowV=e[i].v;long long nowW=e[i].w;rd[nowV]--;cntA[nowV]=(cntA[nowV]+cntA[nowValue])%mod;dp[nowV]+=(dp[nowValue]+cntA[nowValue]*e[i].w)%mod;//cout<<"dp["<<nowV<<"]"<<"=dp["<<nowValue<<"]+"<<e[i].w<<endl;if(rd[nowV]==0){q.push(nowV);}}}
}
int main(){int n,m;scanf("%d%d%d%d%d",&n,&m,&s,&t,&t0);for(int i=1;i<=m;i++){int x,y,z;scanf("%d%d%d",&x,&y,&z);if(x!=y){addEdge(x,y,z);rd[y]++;}}topoSort();total=dp[t];printf("%lld\n",(total+(cntA[t]-1)*t0)%10000);//到达终点的最大时间,再加上从终点回到起点的时间
//(我们在topoSort()方法中并没有计算从终点回到起点的时间)return 0;
}

 

这篇关于C++ P1685 游览的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1099874

相关文章

C++中unordered_set哈希集合的实现

《C++中unordered_set哈希集合的实现》std::unordered_set是C++标准库中的无序关联容器,基于哈希表实现,具有元素唯一性和无序性特点,本文就来详细的介绍一下unorder... 目录一、概述二、头文件与命名空间三、常用方法与示例1. 构造与析构2. 迭代器与遍历3. 容量相关4

C++中悬垂引用(Dangling Reference) 的实现

《C++中悬垂引用(DanglingReference)的实现》C++中的悬垂引用指引用绑定的对象被销毁后引用仍存在的情况,会导致访问无效内存,下面就来详细的介绍一下产生的原因以及如何避免,感兴趣... 目录悬垂引用的产生原因1. 引用绑定到局部变量,变量超出作用域后销毁2. 引用绑定到动态分配的对象,对象

C++读写word文档(.docx)DuckX库的使用详解

《C++读写word文档(.docx)DuckX库的使用详解》DuckX是C++库,用于创建/编辑.docx文件,支持读取文档、添加段落/片段、编辑表格,解决中文乱码需更改编码方案,进阶功能含文本替换... 目录一、基本用法1. 读取文档3. 添加段落4. 添加片段3. 编辑表格二、进阶用法1. 文本替换2

C++中处理文本数据char与string的终极对比指南

《C++中处理文本数据char与string的终极对比指南》在C++编程中char和string是两种用于处理字符数据的类型,但它们在使用方式和功能上有显著的不同,:本文主要介绍C++中处理文本数... 目录1. 基本定义与本质2. 内存管理3. 操作与功能4. 性能特点5. 使用场景6. 相互转换核心区别

C++右移运算符的一个小坑及解决

《C++右移运算符的一个小坑及解决》文章指出右移运算符处理负数时左侧补1导致死循环,与除法行为不同,强调需注意补码机制以正确统计二进制1的个数... 目录我遇到了这么一个www.chinasem.cn函数由此可以看到也很好理解总结我遇到了这么一个函数template<typename T>unsigned

C++统计函数执行时间的最佳实践

《C++统计函数执行时间的最佳实践》在软件开发过程中,性能分析是优化程序的重要环节,了解函数的执行时间分布对于识别性能瓶颈至关重要,本文将分享一个C++函数执行时间统计工具,希望对大家有所帮助... 目录前言工具特性核心设计1. 数据结构设计2. 单例模式管理器3. RAII自动计时使用方法基本用法高级用法

深入解析C++ 中std::map内存管理

《深入解析C++中std::map内存管理》文章详解C++std::map内存管理,指出clear()仅删除元素可能不释放底层内存,建议用swap()与空map交换以彻底释放,针对指针类型需手动de... 目录1️、基本清空std::map2️、使用 swap 彻底释放内存3️、map 中存储指针类型的对象

C++ STL-string类底层实现过程

《C++STL-string类底层实现过程》本文实现了一个简易的string类,涵盖动态数组存储、深拷贝机制、迭代器支持、容量调整、字符串修改、运算符重载等功能,模拟标准string核心特性,重点强... 目录实现框架一、默认成员函数1.默认构造函数2.构造函数3.拷贝构造函数(重点)4.赋值运算符重载函数

C++ vector越界问题的完整解决方案

《C++vector越界问题的完整解决方案》在C++开发中,std::vector作为最常用的动态数组容器,其便捷性与性能优势使其成为处理可变长度数据的首选,然而,数组越界访问始终是威胁程序稳定性的... 目录引言一、vector越界的底层原理与危害1.1 越界访问的本质原因1.2 越界访问的实际危害二、基

c++日志库log4cplus快速入门小结

《c++日志库log4cplus快速入门小结》文章浏览阅读1.1w次,点赞9次,收藏44次。本文介绍Log4cplus,一种适用于C++的线程安全日志记录API,提供灵活的日志管理和配置控制。文章涵盖... 目录简介日志等级配置文件使用关于初始化使用示例总结参考资料简介log4j 用于Java,log4c