医院设置(DFS)

9 篇文章 0 订阅

医院设置

时间限制: 1 Sec  内存限制: 64 MB
[提交][状态][我的提交]

题目描述

设有一棵二叉树,其中圈中的数字表示节点中居民的人口,圈边上的数字表示节点标号。现在要求在某个节点上建立一个医院,使得所有居民所走的路程之和为最小,同时约定,相邻及诶点之间的距离为1.就本图而言,若医院建立在1处,则距离和为4+12+2*20+2*40=136;若医院建立在3处,则距离和为4*2+13+20+40=81……

输入

 输入:第一行为一个整数n,表示树的节点数(n<=100).接下来的n行每行描述了一个节点的状况,包含三个整数,整数之间用空格(一个或多个)分隔,其中:第一个数为居民人口数,第二个树为左链接,为0表示无链接,第三个数为右链接。

输出

 输出:

一个整数,表示距离和。

样例输入

 (如果复制到控制台无换行,可以先粘贴到文本编辑器,再复制)

5
13 2 3
4 0 0
12 4 5
20 0 0
40 0 0

样例输出

81
本来是一道很水的题, 但是忘记判断下一步节点是否存在,导致BFS一直wa,改DFS的时候很自然就去判了节点存在与否,A了才发现BFS的问题。教训阿。。。

#include<iostream>//DFS
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
struct node{
    int num;
    int fa, lch, rch;
}tree[105];
int N, ans = 0x3f3f3f3f, now;
bool vis[105];
void Dfs(int x, int step){
    vis[x] = 1;
	now += step * tree[x].num;
	if(tree[x].lch && (!vis[tree[x].lch]))	Dfs(tree[x].lch, step + 1);
	if(tree[x].rch && (!vis[tree[x].rch]))	Dfs(tree[x].rch, step + 1);
	if(tree[x].fa && (!vis[tree[x].fa]))	Dfs(tree[x].fa, step + 1);
	return ;
}
int main(){
    scanf("%d", &N);
    int a, b, c;
    for(int i = 1; i <= N; i++){
        scanf("%d%d%d", &a, &b, &c);
        tree[i].num = a;
        tree[i].lch = b, tree[i].rch = c;
        tree[b].fa = i, tree[c].fa = i;
    }
    for(int i = 1; i <= N; i++){
		memset(vis, 0, sizeof(vis));
		now = 0;
		Dfs(i, 0);
		ans = min(ans, now);
	}
    printf("%d\n", ans);
    return 0;
}
#include<iostream>//BFS
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<queue>
#include<algorithm>
using namespace std;
struct node{
    int num;
    int fa, lch, rch;
}tree[105];
struct fun{
    int d, pos;
    fun(){}
    fun(int a, int b){d = a,pos = b;}
};
queue<fun>q;
int N;
bool vis[105];
int bfs(int x){
    vis[x] = 1;
    q.push(fun(0, x));
    int ans = 0;
    while(!q.empty()){
        fun tmp = q.front();
        q.pop();
        vis[tmp.pos] = 1;
        ans += tree[tmp.pos].num * tmp.d;
        if(!vis[tree[tmp.pos].fa] && tree[tmp.pos].fa)
            q.push(fun(tmp.d + 1, tree[tmp.pos].fa));
        if(!vis[tree[tmp.pos].lch] && tree[tmp.pos].lch)
            q.push(fun(tmp.d + 1, tree[tmp.pos].lch));
        if(!vis[tree[tmp.pos].rch] && tree[tmp.pos].rch)
            q.push(fun(tmp.d + 1, tree[tmp.pos].rch));
    }
    return ans;
}
int main(){
    scanf("%d", &N);
    int a, b, c;
    for(int i = 1; i <= N; i++){
        scanf("%d%d%d", &a, &b, &c);
        tree[i].num = a;
        tree[i].lch = b, tree[i].rch = c;
        tree[b].fa = i, tree[c].fa = i;
    }
    int ans = 0x3f3f3f3f, now;
    for(int i = 1; i <= N; i++){
        memset(vis, 0, sizeof(vis));
        now = bfs(i);
        ans = min(ans, now);
    }
    printf("%d\n", ans);
    return 0;
}






  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值