ZOJ 3949 Edge to the Root

题意

  给出一颗有n个节点的树,我们想增加一条边在1到x之间,使得d(1,v)的和最小,d(u,v)代表从u到v经过的最少的边,n<=2*10^5。

分析

  这个一看应该就是树形dp。

  如果不连这一条边,这个树本身的d(1,v)的和是多少?显然是每个点的深度的和(根结点深度为0)。那么连一条边(1,v)后,哪些点的深度受到了影响呢?首先它和它所有的子孙结点深度一定让减小。另外我们观察发现,从根结点到v路径上的中间结点以下的点节点深度也会减小。发现了这个规律应该就很好写了,实现的方法也非常多。

  我们定义f[i]是连边(1,i)的d(1,v)的和。那么怎么转移呢?

  当前在结点u,如果fa[u]的f值已经知道,如何求u的f值?我们来看,从(1,fa[u])变为(1,u),哪些点的d(1,v)发生了变化?根据上面的规律很容易找到,u结点本身及其所有的子孙结点的d(1,v)值都减少了1,而1到u路径上的中间结点以下到fa[u]这些结点的d(1,v)值是加了1的。根据这个规律很容易推出所有结点的d值。

  对了,写出来后一直是wa,很费解,出数据也没问题,long long也开了,就是不对。后来发现,对于long long类型的ans我初始化的时候仍然用的2147483647,所以就错了。。改大一点就A掉了···

  

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 #include <algorithm>
 5 #include <vector>
 6 using namespace std;
 7 typedef long long LL;
 8 const int maxn=200000+10;
 9 const int INF=2147483647;
10 
11 vector<int>G[maxn];
12 LL child[maxn],dep[maxn],f[maxn];
13 int T,n,a,b;
14 LL ans;
15 void dfs1(int u,int fa){
16     for(int i=0;i<G[u].size();i++){
17         int v=G[u][i];
18         if(v!=fa){
19             dep[v]=dep[u]+1;
20             dfs1(v,u);
21             child[u]+=child[v];
22         }
23     }
24     return;
25 }
26 int dis[maxn];
27 void dfs(int u,int fa){
28     dis[dep[u]]=u;
29     if(fa!=-1&&fa!=1){
30         f[u]=f[fa]+child[dis[dep[u]/2+1]]-2*child[u];
31     }
32     if(fa==1)
33         f[u]=f[fa];
34     for(int i=0;i<G[u].size();i++){
35         int v=G[u][i];
36         if(v!=fa){
37             dfs(v,u);
38         }
39     }
40     return;
41 }
42 
43 int main(){
44     scanf("%d",&T);
45     for(int t=1;t<=T;t++){
46         scanf("%d",&n);
47         for(int i=1;i<=n;i++)G[i].clear();
48         for(int i=1;i<n;i++){
49             scanf("%d%d",&a,&b);
50             G[a].push_back(b);
51             G[b].push_back(a);
52         }
53         for(int i=1;i<=n;i++)child[i]=1;
54         dep[1]=0;
55         dfs1(1,-1);
56         for(int i=2;i<=n;i++)f[i]=INF;;
57         f[1]=0;
58         for(int i=1;i<=n;i++)f[1]+=dep[i];
59         //cout<<f[1]<<endl;
60         dfs(1,-1);
61         ans=1e14;
62         for(int i=1;i<=n;i++)ans=min(ans,f[i]);
63         printf("%lld\n",ans);
64         /*for(int i=1;i<=n;i++){
65             printf("%d %d\n",i,f[i]);
66         }*/
67     }
68 return 0;
69 }
View Code

 

 

 

 

转载于:https://www.cnblogs.com/LQLlulu/p/8932367.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
目标检测(Object Detection)是计算机视觉领域的一个核心问题,其主要任务是找出图像中所有感兴趣的目标(物体),并确定它们的类别和位置。以下是对目标检测的详细阐述: 一、基本概念 目标检测的任务是解决“在哪里?是什么?”的问题,即定位出图像中目标的位置并识别出目标的类别。由于各类物体具有不同的外观、形状和姿态,加上成像时光照、遮挡等因素的干扰,目标检测一直是计算机视觉领域最具挑战性的任务之一。 二、核心问题 目标检测涉及以下几个核心问题: 分类问题:判断图像中的目标属于哪个类别。 定位问题:确定目标在图像中的具体位置。 大小问题:目标可能具有不同的大小。 形状问题:目标可能具有不同的形状。 三、算法分类 基于深度学习的目标检测算法主要分为两大类: Two-stage算法:先进行区域生成(Region Proposal),生成有可能包含待检物体的预选框(Region Proposal),再通过卷积神经网络进行样本分类。常见的Two-stage算法包括R-CNN、Fast R-CNN、Faster R-CNN等。 One-stage算法:不用生成区域提议,直接在网络中提取特征来预测物体分类和位置。常见的One-stage算法包括YOLO系列(YOLOv1、YOLOv2、YOLOv3、YOLOv4、YOLOv5等)、SSD和RetinaNet等。 四、算法原理 以YOLO系列为例,YOLO将目标检测视为回归问题,将输入图像一次性划分为多个区域,直接在输出层预测边界框和类别概率。YOLO采用卷积网络来提取特征,使用全连接层来得到预测值。其网络结构通常包含多个卷积层和全连接层,通过卷积层提取图像特征,通过全连接层输出预测结果。 五、应用领域 目标检测技术已经广泛应用于各个领域,为人们的生活带来了极大的便利。以下是一些主要的应用领域: 安全监控:在商场、银行
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值