恭喜你看到了这篇题解,他会让你避开很多坑(新手推荐,大佬提些建议嘛)
当然,我不想让大佬像下面这道题中大佬一样。[AHOI2017/HNOI2017]大佬 - 洛谷https://www.luogu.com.cn/problem/P3724
1338:【例3-3】医院设置
时间限制: 1000 ms 内存限制: 65536 KB
提交数: 5111 通过数: 3431
【题目描述】
设有一棵二叉树(如下图),其中圈中的数字表示结点中居民的人口,圈边上数字表示结点编号。现在要求在某个结点上建立一个医院,使所有居民所走的路程之和为最小,同时约定,相邻结点之间的距离为11。就本图而言,若医院建在11处,则距离和=4+12+2×20+2×40=136=4+12+2×20+2×40=136;若医院建在33处,则距离和=4×2+13+20+40=81=4×2+13+20+40=81……
【输入】
第一行一个整数nn,表示树的结点数(n≤100n≤100)。接下来的nn行每行描述了一个结点的状况,包含三个整数,整数之间用空格(一个或多个)分隔,其中:第一个数为居民人口数;第二个数为左链接,为00表示无链接;第三个数为右链接,为00表示无链接。
【输出】
一个整数,表示最小距离和。
【输入样例】
5
13 2 3
4 0 0
12 4 5
20 0 0
40 0 0
【输出样例】
81
这道题我的第一个思路就是“枚”可是这个东西上上下下,不好枚吧!
也没办法了,先把结构体数组写了:
struct node{
int father,left,right,data;
}a[10001];
然后我也不知道该怎么办了,再把输入写了吧:
cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i].data>>a[i].left>>a[i].right;
代码的原型:
#include<bits/stdc++.h>
using namespace std;
struct node{
int data,father,left,right;
}a[10001];
int n;
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i].data>>a[i].left>>a[i].right;
return 0;
}
我们不是创建了father吗,我们就把father定了吧
data | 13 | 4 | 12 | 20 | 40 |
father | 0 | 13 | 13 | 12 | 12 |
left | 4 | 0 | 20 | 0 | 0 |
right | 12 | 0 | 40 | 0 | 0 |
我们需要知道father栏中的数,那么代码遍历之后left和right的father是i
a[a[i].left].father=i;
a[a[i].right].father=i;
代码段:
for(int i=1;i<=n;i++)
{
a[a[i].left].father=i;
a[a[i].right].father=i;
}
遍历(枚举):
for(int i=1;i<=n;i++)
{
memset(v,0,sizeof(v));
ans=min(f(i,0),ans);
}
cout<<ans<<endl;
f函数找父亲,找左孩子,找右孩子,相加,加路程,return,完美!
int f(int x,int d)
{
if(x==0||v[x]==1)
return 0;
v[x]=1;
int l=f(a[x].left,d+1);
int r=f(a[x].right,d+1);
int t=f(a[x].father,d+1);
return l+r+t+a[x].data*d;
}
AC代码:
#include<bits/stdc++.h>
using namespace std;
struct node{
int data,father,left,right;
}a[10001];
int n,ans=INT_MAX,v[10001]={0};
int f(int x,int d)
{
if(x==0||v[x]==1)
return 0;
v[x]=1;
int l=f(a[x].left,d+1);
int r=f(a[x].right,d+1);
int t=f(a[x].father,d+1);
return l+r+t+a[x].data*d;
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i].data>>a[i].left>>a[i].right;
for(int i=1;i<=n;i++)
{
a[a[i].left].father=i;
a[a[i].right].father=i;
}
for(int i=1;i<=n;i++)
{
memset(v,0,sizeof(v));
ans=min(f(i,0),ans);
}
cout<<ans<<endl;
return 0;
}