博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【BZOJ】3302: [Shoi2005]树的双中心 && 2103: Fire 消防站 && 2447: 消防站
阅读量:5896 次
发布时间:2019-06-19

本文共 2141 字,大约阅读时间需要 7 分钟。

Description

Input

第一行为N,1<N<=50000,表示树的节点数目,树的节点从1到N编号。

接下来N-1行,每行两个整数U,V,表示U与V之间有一条边。
再接下N行,每行一个正整数,其中第i行的正整数表示编号为i的节点权值为W(I),树的深度<=100

Output

将最小的S(x,y)输出,结果保证不超过19^9

Sample Input

5
1 2
1 3
3 4
3 5
5
7
6
5
4

Sample Output

14

HINT

选取两个中心节点为2,3

—————————————————————————————

这道题很像树的重心只不过这里要求的重心有两个QAQ

考虑树的深度比较小 我们正常求树的重心的方法就是树的高度h

这样算下来我们因为要求两个重心 那么我们可以O(n)枚举一条边把树变成两个

再O(h)算答案 这样复杂度是可以接受的

注意我们本来的sz指的是子树内的权值和

枚举两个点之后两棵树一开始的重心默认为1棵 是1 1棵是u

然后在贪心往下找 

当然这样可能会有问题那就是因为算的是min(dis[x][u],dis[x][v])

这样的话我们本来是贪心树里面的到这个点 但是这样肯定会错

这样的话其实也影响答案 因为这个只会使当前解比真实解大

最优解的情况是不会受影响的 这样就可以解决这道问题辣

tips sum+=sz[x](x->2-n)

这样其实就是在算路径和 这个转换使代码异常优美2333

#include
#include
#include
#define LL long longusing std::min;using std::swap;const int M=1e5+7;const LL inf=0x3f3f3f3f;char buf[M*33],*ptr=buf-1;int read(){ int ans=0,f=1,c=*++ptr; while(c<'0'||c>'9'){
if(c=='-') f=-1; c=*++ptr;} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=*++ptr;} return ans*f;}LL ans=inf,sz[M],mx[M],sec[M],sum,w[M];int T,n,fa[M],dep[M];int first[M],cnt;struct node{
int from,to,next;}e[2*M];void ins(int a,int b){e[++cnt]=(node){a,b,first[a]}; first[a]=cnt;}void insert(int a,int b){ins(a,b); ins(b,a);}void dfs(int x,int f){ sz[x]=w[x]; mx[x]=sec[x]=0; for(int i=first[x];i;i=e[i].next){ int now=e[i].to; if(now==f) continue; fa[now]=x; dep[now]=dep[x]+1; dfs(now,x); sz[x]+=sz[now]; if(sz[now]>sz[mx[x]]) sec[x]=mx[x],mx[x]=now; else if(sz[now]>sz[sec[x]]) sec[x]=now; }}int main(){ fread(buf,1,sizeof(buf),stdin); int x,y; n=read(); for(int i=1;i
sz[sec[x]]&&mx[x]!=u) y=mx[x]; else y=sec[x]; if(sz[y]*2>sz[1]) x=y,nowh=nowh-sz[y]*2+sz[1]; else break; } x=u; while(1){ if(sz[mx[x]]*2>sz[u]) nowh=nowh-sz[mx[x]]*2+sz[u],x=mx[x]; else break; } ans=min(ans,nowh); for(x=v;x;x=fa[x]) sz[x]+=sz[u]; } printf("%lld\n",ans); return 0;}
View Code

 

转载于:https://www.cnblogs.com/lyzuikeai/p/7598526.html

你可能感兴趣的文章
26. Remove Duplicates from Sorted Array
查看>>
在使用AngularJS的过程中了解Promise(二)
查看>>
ArrayList源码解析
查看>>
基于SpringMVC、Maven以及Mybatis的环境搭建
查看>>
可见面判别算法---区域细分算法
查看>>
清理恢复文本框的默认值
查看>>
【原创】如何在vim中使用tab进行python代码补全
查看>>
Struts秘籍之起式:第1.3式:迁移至Struts 1.1
查看>>
绿色PLSQL/Developer搭配Oracle精简客户端使用
查看>>
ViewPager Banner(广告墙)
查看>>
Spring Cloud 入门教程(二): 服务消费者(rest+ribbon)(Greenwich.RELEASE)
查看>>
iOS开发20:Navigation Bar的简单设置
查看>>
iOS开发24:使用SQLite3存储和读取数据
查看>>
GMF树形布局 2 实现展开/折叠
查看>>
Cocos2dx 2.0x Touch事件
查看>>
php判断是否登录
查看>>
Yii2 Unable to verify your data submission 错误-CSRF
查看>>
angularjs-paste-upload
查看>>
解除 Linux 系统的最大进程数和最大文件打开数限制
查看>>
Java类的修饰符判断:java.lang.reflect.Modifier
查看>>