医院设置
Posted adelalove
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了医院设置相关的知识,希望对你有一定的参考价值。
题目描述
设有一棵二叉树,如图:
其中,圈中的数字表示结点中居民的人口。圈边上数字表示结点编号,现在要求在某个结点上建立一个医院,使所有居民所走的路程之和为最小,同时约定,相邻接点之间的距离为1。如上图中,
若医院建在1 处,则距离和=4+12+2*20+2*40=136;若医院建在3 处,则距离和=4*2+13+20+40=81……
输入输出格式
输入格式:
第一行一个整数n,表示树的结点数。(n≤100)
接下来的n行每行描述了一个结点的状况,包含三个整数,整数之间用空格(一个或多个)分隔,其中:第一个数为居民人口数;第二个数为左链接,为0表示无链接;第三个数为右链接。
输出格式:
一个整数,表示最小距离和。
输入输出样例
输入样例#1:
5
13 2 3
4 0 0
12 4 5
20 0 0
40 0 0
输出样例#1:
81
解:
此题暴力枚举在哪个点设置医院,然后以那个点为根进行DFS即可,
复杂度O(n^2)
1 #include<bits/stdc++.h> 2 #define ll long long 3 #define DB double 4 using namespace std; 5 const int N=1e6+10; 6 struct node{ 7 int u,v,ne; 8 }e[N]; 9 int h[N],tot,a[N],n; 10 void add(int u,int v) 11 { 12 tot++;e[tot]=(node){u,v,h[u]};h[u]=tot; 13 } 14 ll ans,tmp; 15 void dfs(int u,int fa,int d) 16 { 17 tmp+=1ll*a[u]*d; 18 for(int i=h[u],rr;i;i=e[i].ne) 19 { 20 rr=e[i].v; 21 if(rr!=fa) dfs(rr,u,d+1); 22 } 23 } 24 int main() 25 { 26 scanf("%d",&n); 27 for(int i=1,l,r;i<=n;++i) 28 { 29 scanf("%d",&a[i]); 30 scanf("%d%d",&l,&r); 31 if(l) add(i,l),add(l,i); 32 if(r) add(i,r),add(r,i); 33 } 34 ans=1e12; 35 for(int i=1;i<=n;++i) 36 { 37 tmp=0; 38 dfs(i,0,0); 39 ans=min(ans,tmp); 40 } 41 printf("%lld",ans); 42 fclose(stdin);fclose(stdout); 43 return 0; 44 }
也可以用树形DP来写,复杂度O(n)
ok[i]表示以i为根的最优答案,首先我们预处理出ok[1]
sz[i]表示i这棵子树的大小(节点数目之和)
对于( u -> v ) 已知ok[u]
我们只需要减去sz[v],加上除了sz[v]以外的节点数目
即ok[v]=ok[u]-sz[v]+sz[1]-sz[v]=ok[u]+sz[1]-2*sz[v]
得解。
1 #include<bits/stdc++.h> 2 #define ll long long 3 #define DB double 4 using namespace std; 5 const int N=1e4+10; 6 struct node{ 7 int u,v,ne; 8 }e[N]; 9 int h[N],tot,a[N],n,sz[N]; 10 void add(int u,int v) 11 { 12 tot++;e[tot]=(node){u,v,h[u]};h[u]=tot; 13 } 14 ll ans,tmp,ok[N]; 15 void dfs1(int u,int fa,int d) 16 { 17 ans+=1ll*a[u]*d; 18 for(int i=h[u],rr;i;i=e[i].ne) 19 { 20 rr=e[i].v; 21 if(rr!=fa) dfs1(rr,u,d+1),sz[u]+=sz[rr]; 22 } 23 } 24 void dfs2(int u,int fa) 25 { 26 ans=min(ans,ok[u]); 27 for(int i=h[u],rr;i;i=e[i].ne) 28 { 29 rr=e[i].v; 30 if(rr!=fa) 31 { 32 ok[rr]=ok[u]+sz[1]-2*sz[rr]; 33 dfs2(rr,u); 34 } 35 } 36 } 37 int main() 38 { 39 scanf("%d",&n); 40 for(int i=1,l,r;i<=n;++i) 41 { 42 scanf("%d",&a[i]);sz[i]=a[i]; 43 scanf("%d%d",&l,&r); 44 if(l) add(i,l),add(l,i); 45 if(r) add(i,r),add(r,i); 46 } 47 dfs1(1,0,0);ok[1]=ans; 48 dfs2(1,0); 49 printf("%lld",ans); 50 fclose(stdin);fclose(stdout); 51 return 0; 52 }
以上是关于医院设置的主要内容,如果未能解决你的问题,请参考以下文章