蓝桥杯 生命树java_蓝桥杯图专题

蓝桥杯图专题

蓝桥杯图专题

【问题描述】

很久以前,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

5

1 2 2

1 3 1

2 4 5

2 5 4

样例输出1

135

【输出格式】

大臣J从城市4到城市5要花费135的路费。

【思路】

以每一个城市为起点暴力搜索其能到达的最远的城市,最大的结果即为所求。可以通过75%的数据。

注意=

由于是无向图,在存储数据的时候边双向关联的。以所给样例为例,若标记像往常dfs一样在for循环内标记,会出现从1结点进入2结点,然后2结点又遍历1结点的情况,1结点城市走了两遍,这是不允许的。标记应该在进入递归函数时。

package _2013;

import java.util.ArrayList;

import java.util.List;

import java.util.Scanner;

/**

* @author JohnnyLin

* @version Creation Time:2020年10月13日 下午12:45:32

* https://www.dotcpp.com/oj/problem1438.html3

*

*/

public class _大臣的旅费 {

static int n,ans;

static List [] node;

static int map[][];

static boolean vis[];

static void dfs(int father,int dist) {

//System.out.println(father+" "+dist);

vis[father]=true;

for(int i=0;i< node[father].size();i++) {

int son=node[father].get(i);

if(!vis[son]) {

//vis[son]=true; 错误写法

dist+=map[father][son];

if(dist>ans) {

ans=dist;

}

dfs(son, dist);

dist-=map[father][son];

//vis[son]=false; 错误写法

}

}

vis[father]=false;

}

public static void main(String[] args) {

// TODO Auto-generated method stub

/*

012

11121314

*/

Scanner reader=new Scanner(System.in);

n=reader.nextInt();

map=new int[n+1][n+1];

node=new ArrayList[n+1];

vis=new boolean[n+1];

for(int i=1;i<=n;i++)

node[i]=new ArrayList<>();

for (int i = 1; i < n; i++) {

int p=reader.nextInt();

int q=reader.nextInt();

int d=reader.nextInt();

node[p].add(q);

node[q].add(p);

map[p][q]=d;

map[q][p]=d;

}

for (int i = 1; i <=n; i++) {

dfs(i, 0);

vis=new boolean[n+1];

}

System.out.println((21+ans)*ans/2);

}

}

另一种写法:

这题就是求一棵树上的距离最远的两个点的距离,也就是最长路径问题。

最长路径问题就是:

假设 s-t这条路径为树的直径,或者称为树上的最长路径。现有结论,从任意一点u出发搜到的最远的点一定是s、t中的一点,然后在从这个最远点开始搜,就可以搜到另一个最长路的端点,即用两遍广搜就可以找出树的最长路。

package _2013;

/**

* @author JohnnyLin

* @version Creation Time:2020年10月13日 下午2:52:17

*/

import java.util.ArrayList;

import java.util.Scanner;

public class _大臣的旅费1 {

public static int n;

static int Max=Integer.MIN_VALUE;

//代表最长距离的起点城市

static int point;

//城市结构体

//声明动态数组 ArrayList map1=new ArrayList<>();看成A数据类型 类似于Integer

//数组:A [] map2=new A();

//两句合在一起就相当于:声明了一个数组map2里面的数据元素是A类型的 而A类型的数据是edge类的

static ArrayList[] map;

static class edge{

public int P,Q,D;

public edge(int p,int q,int d) {

P=p;

Q=q;

D=d;

}

}

private static void getResult() {

boolean [] vis=new boolean[n+1];

//进行两遍深搜 第一遍深搜搜索出最长路径的起点,第二次深搜走出最长路径

dfs(1,vis,0);

//布尔数组再次初始化

vis=new boolean[n+1];

dfs(point,vis,0);

int res=(11+10+Max)*Max/2;

System.out.println(res);

}

private static void dfs(int start,boolean[] vis,int dis ) {

vis[start]=true;

//枚举从start出发 可以到达的下一个城市

for(int i=0;i

edge temp=map[start].get(i);

if(!vis[temp.Q]) {//若这两个城市的高速公路没有访问过 则访问

dis+=temp.D;

if(dis>Max) {//若这条路的距离大于max 更新max

Max=dis;

point=temp.Q;//并且存储该城市

}

dfs(temp.Q,vis,dis);//沿着该点往下搜索

//需要恢复状态 因为在该条高速路走到黑之后进行下一条高速路的深搜

dis-= temp.D;

}

}

}

public static void main(String[] args) {

Scanner reader=new Scanner(System.in);

n=reader.nextInt();

//由n个城市 每个城市都有自己的map

map=new ArrayList[n+1];

for(int i=1;i<=n;i++)

//将每个城市的map都实例化为存储edge(高速路)对象的链表

map[i]=new ArrayList();

for(int j=1;j

int p=reader.nextInt();

int q=reader.nextInt();

int d=reader.nextInt();

map[p].add(new edge(p,q,d));

map[q].add(new edge(q,p,d));

}

reader.close();

getResult();

}

}

生命之树

在X森林里,上帝创建了生命之树。

他给每棵树的每个节点(叶子也称为一个节点)上,都标了一个整数,

代表这个点的和谐值。上帝要在这棵树内选出一个非空节点集S,

使得对于S中的任意两个点a,b,都存在一个点列 {a, v1, v2, ..., vk, b}

使得这个点列中的每个点都是S里面的元素,且序列中相邻两个点间有一条边相连。

在这个前提下,上帝要使得S中的点所对应的整数的和尽量大。

这个最大的和就是上帝给生命之树的评分。

经过atm的努力,他已经知道了上帝给每棵树上每个节点上的整数。

但是由于 atm 不擅长计算,他不知道怎样有效的求评分。

他需要你为他写一个程序来计算一棵树的分数。

「输入格式」

第一行一个整数 n 表示这棵树有 n 个节点。

第二行 n 个整数,依次表示每个节点的评分。

接下来 n-1 行,每行 2 个整数 u, v,表示存在一条 u 到 v 的边。

由于这是一棵树,所以是不存在环的。

「输出格式」

输出一行一个数,表示上帝给这棵树的分数。

「样例输入」

5

1 -2 -3 4 5

4 2

3 1

1 2

2 5

「样例输出」

8

「数据范围」

对于 30% 的数据,n <= 10

对于 100% 的数据,0 < n <= 10^5, 每个节点的评分的绝对值不超过 10^6 。

资源约定:

峰值内存消耗(含虚拟机) < 256M

CPU消耗 < 3000ms

这是一颗无向赋权图,要求是找一棵最大的连通块(生成树)。

08bc91fdece8f2233713c5e656bfd96f.png要求的就是:

ff839b8a397a3a31919332e701bd3711.png

package _2015;

import java.util.ArrayList;

import java.util.List;

import java.util.Scanner;

/**

* @author JohnnyLin

* @version Creation Time:2020年10月12日 下午11:04:40

*/

public class _t10生命之树 {

static int n;

static long ans;

//每个数组元素为列表

static List nodeEdge[];

static long[] value;

static void dfs(int son,int father) {

for(int i=0;i

int next=nodeEdge[son].get(i);

if(next!=father) {//相邻结点不是父结点

//子树最大连通块为负值则不要了 比如说3号结点的子树为负值

dfs(next, son);

value[son]+=Math.max(0,value[next]);

//System.out.println(value[next]);

}

}

//根结点可能是负值

ans=Math.max(ans,value[son]);

//System.out.println(ans);

}

public static void main(String[] args) {

Scanner reader=new Scanner(System.in);

n=reader.nextInt();

value=new long[n+1];

nodeEdge=new ArrayList[n+1];

for(int i=1;i<=n;i++) {

value[i]=reader.nextInt();

nodeEdge[i]=new ArrayList();

}

for(int i=1;i

int u=reader.nextInt();

int v=reader.nextInt();

nodeEdge[u].add(v);

nodeEdge[v].add(u);

}

dfs(1,-1);

System.out.println(ans);

}

}

另一种写法:

参考了网上代码的

package 第六届;

import java.util.LinkedList;

import java.util.List;

import java.util.Scanner;

public class 生命树_网友版 {

static int[] nodeValue;//存放各个点的和谐值

static List[] point;//存放各个点的包含的邻接边

static int[] value;//存放以某个点为根节点情况下的最大和谐值和

static int ans=0;//记录最大结果

static void dfs(int son,int father) {

value[son]=nodeValue[son];//以son为根节点,一开始时其最大和谐值为它本身

for(int i=0;i

int next=point[son].get(i);

//当枚举的下一个结点是son先前经过的点father 跳过 防止绕圈

if(next==father)continue;//如果都continue掉说明这个点是叶子结点

dfs(next,son);

//回溯(子节点平行状态都走完没得走了或者说状态没得转移了才会回溯)得到父节点与子节点和

if(value[next]>0)//子节点的和谐值

value[son]+=value[next];

ans=Math.max(ans, value[son]);

}

}

public static void main(String[] args) {

Scanner reader=new Scanner(System.in);

int n=reader.nextInt();

nodeValue=new int [n+1];

value=new int[n+1];

point=new LinkedList[n+1];

for(int i=1;i<=n;i++) {

nodeValue[i]=reader.nextInt();

point[i]=new LinkedList();

}

for(int i=1;i

int x=reader.nextInt();

int y=reader.nextInt();

point[x].add(y);

point[y].add(x);

}

dfs(1,-1);//从0号结点开始搜索 假设它的父节点为-1可以为其他的无关量

System.err.println(ans);

}

}

注意:java里调用栈最多一万层,因此使用dfs最多可以通过n <= 10,30%的数据

蓝桥杯图专题相关教程

[蓝桥杯2017初赛]Excel地址(新型进制转换)(思路)

[蓝桥杯2017初赛]Excel地址(新型进制转换)(思路) 这道题自己想了好久没想明白,感觉有规律但就是不知道怎么去找。。。 看完别人的代码后,自己再想想,好有道理啊!!! #includeiostream#includestdio.h#includestring.h#includemath.h#includealgorithm

[蓝桥杯2017初赛]九宫幻方 (全排列匹配)

[蓝桥杯2017初赛]九宫幻方 (全排列匹配) 使用全排列函数,对1~9进行全排列,先验证一下是不是在题目所给的矩阵基础上填写的,然后在验证是否满足三阶幻方的要求。如果满足总计数器就+1,最后判断一下有几个满足条件的,按题目要求输出结果即可。 #includeio

蓝桥杯第九届省赛B组c/c++

蓝桥杯第九届省赛B组c/c++ 1.第几天 2000年的1月1日,是那一年的第1天。 那么,2000年的5月4日,是那一年的第几天? 注意:需要提交的是一个整数,不要填写任何多余内容。 解题思路: 直接算或者借助Excel表 ,2000年1月1日再加124天=2000年5月4日,所以是第12

蓝桥秘密冲刺计划(10.13)解码

蓝桥秘密冲刺计划(10.13)解码 定位:2020年第十一届蓝桥杯省赛C/C++ B组试题G(7月试题) 原题: 属性:字符读入+模拟 难度:破壳 独白: 这题我们采用边读取字符边模拟判断的策略来做,即用这样的while循环: while((ch=getchar())!='\n') 来解决问题。 读

[蓝桥杯2017初赛]9数算式(思路+水题)

[蓝桥杯2017初赛]9数算式(思路+水题) 说实话,这道题拖了我好久,我第一眼看题:这题稳了,不就是4,5全排列么。 但是做完后答案只有300多,然后再改,还是300多,就去看题解去了,才发现不一定非是4位数 5位数,还可能是3位数 6位数,2位数 7位数,1位数 8

[蓝桥杯2017初赛]纸牌三角形 (思路)

[蓝桥杯2017初赛]纸牌三角形 (思路) 真的是被秀了一脸!! 考虑旋转,镜像后,牌的顺序不变的情况下,有六种,所以最后结果除以6就行了。 #includeiostream#includestdio.h#includestring.h#includemath.h#includealgorithm#define ll long long#includeset

Python蓝桥杯练习基础题 杨辉三角形

Python蓝桥杯练习基础题 杨辉三角形 0 引言 马上就要进行蓝桥杯的省赛了,最近刷了一些蓝桥杯官网上的一些基础题,这里对杨辉三角形的python实现来进行一个思路的自我总结。 1 杨辉三角形 首先,直观认识一下杨辉三角;这里摘取一张百度百科上的杨辉三角形图

蓝桥-递增三元组-蓝桥

蓝桥-递增三元组-蓝桥 手动求解一下会发现,B数组是关键 若固定b = B[i] a中的可能的取值是:a0 ----- at小于等于b的元素下标(小于b的个数) c中的可能取值是:大于c的元素下标ct ---- cn 固定b后可以很容易的判断出a,c中的元素个数 这是一个分步策略,最后可

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
【优质项目推荐】 1、项目代码均经过严格本地测试,运行OK,确保功能稳定后才上传平台。可放心下载并立即投入使用,若遇到任何使用问题,随时欢迎私信反馈与沟通,博主会第一时间回复。 2、项目适用于计算机相关专业(如计科、信息安全、数据科学、人工智能、通信、物联网、自动化、电子信息等)的在校学生、专业教师,或企业员工,小白入门等都适用。 3、该项目不仅具有很高的学习借鉴价值,对于初学者来说,也是入门进阶的绝佳选择;当然也可以直接用于 毕设、课设、期末大作业或项目初期立项演示等。 3、开放创新:如果您有一定基础,且热爱探索钻研,可以在此代码基础上二次开发,进行修改、扩展,创造出属于自己的独特应用。 欢迎下载使用优质资源!欢迎借鉴使用,并欢迎学习交流,共同探索编程的无穷魅力! 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值