蓝桥杯--- 历届试题 大臣的旅费 (DFS & Vector)
问题描述
很久以前,T王国空前繁荣。为了更好地管理国家,王国修建了大量的快速路,用于连接首都和王国内的各大城市。
为节省经费,T国的大臣们经过思考,制定了一套优秀的修建方案,使得任何一个大城市都能从首都直接或者通过其他大城市间接到达。同时,如果不重复经过大城市,从首都到达每个大城市的方案都是唯一的。
J是T国重要大臣,他巡查于各大城市之间,体察民情。所以,从一个城市马不停蹄地到另一个城市成了J最常做的事情。他有一个钱袋,用于存放往来城市间的路费。
聪明的J发现,如果不在某个城市停下来修整,在连续行进过程中,他所花的路费与他已走过的距离有关,在走第x千米到第x+1千米这一千米中(x是整数),他花费的路费是x+10这么多。也就是说走1千米花费11,走2千米要花费23。
J大臣想知道:他从某一个城市出发,中间不休息,到达另一个城市,所有可能花费的路费中最多是多少呢?
输入的第一行包含一个整数n,表示包括首都在内的T王国的城市数
城市从1开始依次编号,1号城市为首都。
接下来n-1行,描述T国的高速路(T国的高速路一定是n-1条)
每行三个整数Pi, Qi, Di,表示城市Pi和城市Qi之间有一条高速路,长度为Di千米。
输出一个整数,表示大臣J最多花费的路费是多少。
1 2 2
1 3 1
2 4 5
2 5 4
大臣J从城市4到城市5要花费135的路费。
开始的思路是从每一个点出发,求出其最长距离,然后输出就可以了,这样每个节点都会作为开始查找其所有路径的长度,较浪费时间,因为其为树的结构,其实没有必要把每一个节点作为起始节点进行查找。。。
开始的时候就知道是用树这种数据结构,但是由于是普通树,不太会存储,所以索性就用图了,但是这样的话会浪费掉很多的空间,并且在扫描的时候会全部扫面造成大量的时间浪费,并且图结构的存储造成数组开辟也受到一定的限制,另外最后关键是结果还不正确,一组WR ,一组运行时间错误,估计就是数组的受限原因造成的。。。另外一组的WR现在还不知道具体是错在什么地方,不知道会不会只数组的原因,以后改正。。。
代码:
#include <iostream>
#include <string.h>
#include <cstdio>
using namespace std;
#define INF 0x3f3f3f3f
#define MAX 1500
int n,x,y,v,now;
int Max=-INF;
int map[1500][1500],dis[1500][1500];
bool vis[1500];
long long sum(int x){
return (11+10+x)*x/2;
} void dfs(int i,int count){
vis[i]=1;
for(int x=1;x<n;x++){
if(x==i) continue;//
if(map[i][x] && vis[x]==0){
dis[now][x]=dis[x][now]=count+dis[i][x];
dfs(x,count+dis[i][x]);
if(Max<dis[now][x]) Max=dis[now][x];
}
}
vis[i]=0;
} int main (){
while(cin>>n){
Max=-INF;
memset(map,0,sizeof(map));
memset(dis,0,sizeof(dis));
memset(vis,0,sizeof(vis));
for(int i=0;i<n-1;i++){
cin>>x>>y>>v;
map[x][y]=map[y][x]=1;
dis[x][y]=dis[y][x]=v;
}
for(int i=1;i<=n;i++){
now=i;
dfs(i,0);
}
cout<<sum(Max)<<endl;
}
return 0;
}
另外一种比较恰当的普通建树方式是用vector这样的数据结构进行存储,很好用,也没有什么超时之列的问题。。。
下面具体说说这道题的思路,由于满足树这样的结构,所以起始先找出距离根节点代价(也就是w值)最远的,然后以这个作为起点遍历,当然就是最长的路径了,起始最终转化为的就是最长路径的查找。具体原因仔细想想就知道了,不太好表达。。。
为了实现完整的查找,就需要两次的遍历,第一次查找从根节点开始的w消耗值最大的路径,查找出这条路径的终点,然后用该节点作为起始节点再次遍历,这样所获的就是要查找的结果了。。。
#include<iostream>
#include<vector>
#include<cstring>
#include<cstdio>
#define INF 0x3f3f3f3f using namespace std;
vector<int> G[1000005];
vector<int> E[1000005];
bool vis[1000005];
int d[1000005];
void init()
{
memset(vis, 0, sizeof(vis));
}
void dfs(int u){
vis[u]=1;
int size=G[u].size();
for(int i=0;i<size;i++){
int v=G[u][i];
if(!vis[v]){
d[v]=d[u]+E[u][i];
dfs(v);
}
}
}
int main()
{
int n;
cin>>n;
int u,v,w; for(int i=0;i<n-1;i++)
{
scanf("%d%d%d",&u,&v,&w);
G[u-1].push_back(v-1);
E[u-1].push_back(w); G[v-1].push_back(u-1);
E[v-1].push_back(w);
}
// 第一遍
init();
for(int i=0;i<n;i++)
d[i]=(i==0?0:INF);
dfs(0);
int start=0;
int max=-1;
for(int i=0;i<n;i++)
if(d[i]>max&&d[i]!=INF)
{
max=d[i];
start=i; }
init();
for(int i=0;i<n;i++)
d[i]=(i==start?0:INF);
dfs(start);
int ans=-1;
for(int i=0;i<n;i++)
if(d[i]>ans&&d[i]!=INF)
ans=d[i];
ans=10*ans+ans*(ans+1)/2;
cout<<ans<<endl;
}
另外注意Vector的使用是一定注意其下标和输入数据的存储关系,因为在之后的处理过程中,vector数组的下表就是节点,如G[0]就是0这个节点,如果再输入的时候不加改变的把题目给出的节点输入的话就会,就错位了0节点存储的就是1所对应的节点了,上面是从G[0]开始存储的,这样也就减1了,但是稍显麻烦,所以从下表为1的开始存储就直接了,更加明了。。。
//去掉一下注释行查看详细深搜过程。
#include<iostream>
#include<vector>
#include<cstring>
#include<cstdio>
#define INF 0x3f3f3f3f using namespace std;
vector<int> G[1000005];//建立两个数组vector分别存储节点信息和路径权值
vector<int> E[1000005];
bool vis[1000005];
int d[1000005]; void dfs(int u){
vis[u]=1;
int size=G[u].size();
for(int i=0;i<size;i++){
int v=G[u][i];
if(!vis[v]){
d[v]=d[u]+E[u][i];
// cout<<"父节点为:"<<u<<" 子节点为:" <<v<<endl;
dfs(v);
}
}
}
int main()
{
int n;
while(cin>>n){
int u,v,w;
for(int i=0;i<=n;i++){//由于多组测试数据,所以必须清空vector
G[i].clear();
E[i].clear();
}
for(int i=0;i<n-1;i++)
{
scanf("%d%d%d",&u,&v,&w);
G[u].push_back(v);
E[u].push_back(w); G[v].push_back(u); //其实在第一遍的时候使用不到的,只是在之后的逆向搜索的时候才会用到
E[v].push_back(w);
}
//节点信息输出
// for(int i=1;i<=n;i++){
// cout<<i<<"子节点为:";
// for(int j=0;j<G[i].size();j++)
// cout<<G[i][j]<<' ';
// cout<<endl;
// }
// cout<<endl<<endl; // 第一遍
// cout<<endl<<endl<<"第二次遍历过程..."<<endl;
memset(vis, 0, sizeof(vis));
for(int i=0;i<n;i++)
d[i]=(i==1?0:INF);
dfs(1);
int start=1;
int max=-1;
for(int i=1;i<=n;i++)
if(d[i]>max&&d[i]!=INF)
{
max=d[i];
start=i;
} //第二次遍历
// cout<<endl<<endl<<"第二次遍历过程..."<<endl;
memset(vis, 0, sizeof(vis));
for(int i=0;i<=n;i++)
d[i]=(i==start?0:INF);
dfs(start);
int ans=-1;
for(int i=0;i<=n;i++)
if(d[i]>ans&&d[i]!=INF)
ans=d[i];
ans=10*ans+ans*(ans+1)/2;
cout<<ans<<endl;
}
}
蓝桥杯--- 历届试题 大臣的旅费 (DFS & Vector)的更多相关文章
- 转 蓝桥杯 历届试题 大臣的旅费 [ dfs 树的直径 ]
题解: 求树的直径. 转一篇博客:http://www.cnblogs.com/hanyulcf/archive/2010/10/23/tree_radius.html 树的直径是指树的最长简单路.求 ...
- Java实现 蓝桥杯 历届试题 大臣的旅费
问题描述 很久以前,T王国空前繁荣.为了更好地管理国家,王国修建了大量的快速路,用于连接首都和王国内的各大城市. 为节省经费,T国的大臣们经过思考,制定了一套优秀的修建方案,使得任何一个大城市都能从首 ...
- 蓝桥杯 历届试题 剪格子(dfs搜索)
历届试题 剪格子 时间限制:1.0s 内存限制:256.0MB 问题描述 如下图所示,3 x 3 的格子中填写了一些整数. +--*--+--+ |* || +--****--+ ||* | ** ...
- 蓝桥杯 历届试题 网络寻路(dfs搜索合法路径计数)
X 国的一个网络使用若干条线路连接若干个节点.节点间的通信是双向的.某重要数据包,为了安全起见,必须恰好被转发两次到达目的地.该包可能在任意一个节点产生,我们需要知道该网络中一共有多少种不同的转发路径 ...
- 蓝桥杯历届试题 危险系数(dfs或者并查集求无向图关于两点的割点个数)
Description 抗日战争时期,冀中平原的地道战曾发挥重要作用. 地道的多个站点间有通道连接,形成了庞大的网络.但也有隐患,当敌人发现了某个站点后,其它站点间可能因此会失去联系. 我们来定义一个 ...
- 蓝桥杯-历届试题 剪格子(dfs)
历届试题 剪格子 时间限制:1.0s 内存限制:256.0MB 问题描述 如下图所示,3 x 3 的格子中填写了一些整数. +--*--+--+|10* 1|52|+--**** ...
- 蓝桥杯历届试题 地宫取宝 dp or 记忆化搜索
问题描述 X 国王有一个地宫宝库.是 n x m 个格子的矩阵.每个格子放一件宝贝.每个宝贝贴着价值标签. 地宫的入口在左上角,出口在右下角. 小明被带到地宫的入口,国王要求他只能向右或向下行走. 走 ...
- 蓝桥杯 历届试题 幸运数 dfs
历届试题 幸运数 时间限制:1.0s 内存限制:256.0MB 问题描述 幸运数是波兰数学家乌拉姆命名的.它采用与生成素数类似的"筛法"生成 . 首先从1开始写出自然数1,2, ...
- 蓝桥杯 历届试题 剪格子 dfs
历届试题 剪格子 时间限制:1.0s 内存限制:256.0MB 问题描述 如下图所示,3 x 3 的格子中填写了一些整数. +--*--+--+ |10* 1|52| +--****--+ |20 ...
随机推荐
- Jersey框架一:Jersey RESTful WebService框架简介
Jersey系列文章: Jersey框架一:Jersey RESTful WebService框架简介 Jersey框架二:Jersey对JSON的支持 Jersey框架三:Jersey对HTTPS的 ...
- Android 使用AIDL调用外部服务
好处:多个应用程序之间建立共同的服务机制,通过AIDL在不同应用程序之间达到数据的共享和数据相互操作, 本文包括: 1 .创建AIDL 服务端.2 .创建AIDL 客户端. 3.客户端调用服务端提供的 ...
- Subversion与TortoiseSVN的安装
首先介绍一下Subversion与TortoiseSVN两者之间的关系: Subversion是一种集中分享信息的系统,它的核心是版本库,储存所有的数据.版本库按照文件树形式储存数据-包括文件和目录. ...
- 【linux】bash常用快捷键
Ctrl + r:逆向搜索命令历史 Ctrl + l:清屏 Ctrl + c:终止命令 Ctrl + u:删除光标前的指令 Ctrl + k:删除光标后的指令 Ctrl + d:退出登陆
- ASIHttpRequest addRequestHeader的处理
我现在用到了ASIHttpRequest来读取数据,这时候我发现里面的头在很多时候都是一样的.如用户的令牌,设备类型,ios版本,软件版本等 [self.request addRequestHeade ...
- 重绘TabControl
本文转载自:http://blog.csdn.net/conmajia/article/details/7596718 作者:野比 (conmajia@gmail.com) 时间:May, 2012 ...
- 【XML配置文件读取】使用jdom读取XML配置文件信息
在项目中我们经常需要将配置信息写在配置文件中,而XML配置文件是常用的格式. 下面将介绍如何通过jdom来读取xml配置文件信息. 配置文件信息 <?xml version="1.0& ...
- Bind 跨域名别名解析的问题
我有一个域名 aaa.net 已经生效 ,并且下面有 xx的 A记录:现在我还有一个 aaa.com域名 ,我想用 别名方式把它下面 某个 记录以别名方式解析到 xx.aaa.net上去.应该在aaa ...
- TX Textcontrol 使用总结二——常见异常
在使用Tx text control中间,我们经过会遇到在开发人员自己的电脑上我们的程序是可以正常允许的,但当部署到客户端却往往会发现一些意想不到的问题 如下所示: 未能加载文件或程序集“txtool ...
- [系统开发] FileMaker进销存系统
一.简介 这是我用 FileMaker 编写的进销存系统: FileMaker 是一种在欧美流行的桌面型数据库:它使用非常方便,功能也很强大,用户可以在它上面开发自己的系统: 开发时间:2008年 二 ...