1338:【例3-3】医院设置(深搜、广搜)

【题目链接】

1338:【例3-3】医院设置

【题目描述】

设有一棵二叉树(如下图),其中圈中的数字表示结点中居民的人口,圈边上数字表示结点编号。现在要求在某个结点上建立一个医院,使所有居民所走的路程之和为最小,同时约定,相邻结点之间的距离为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

【题解】

深搜

#include <iostream>
#include <cstring>
#include <climits>

using namespace std;
int sum,vis[105],ans =INT_MAX;
struct node{
    int val;
    int left,right,parent;
};
node node[105];
void dfs(int step,int pos){
    sum+=step*node[pos].val;//计算路径
    if(node[pos].parent && !vis[node[pos].parent]){//有父节点 并且父节点并没有被访问
        vis[node[pos].parent]=1;//注意点:访问后要设置值为1
        dfs(step+1,node[pos].parent);
    }
    if(node[pos].left && !vis[node[pos].left]){
        vis[node[pos].left]=1;
        dfs(step+1,node[pos].left);//注意点:访问后要设置值为1
    }
    if(node[pos].right && !vis[node[pos].right]){
        vis[node[pos].right]=1;
        dfs(step+1,node[pos].right);//注意点:访问后要设置值为1
    }
}
int main(){
    int n,i;
    cin>>n;
    for(i=1;i<=n;i++){
        cin>>node[i].val>>node[i].left>>node[i].right;
        node[node[i].left].parent = i;//此处记录的结点位置 不是结点的值
        node[node[i].right].parent = i;
    }
    for(i=1;i<=n;i++){
        sum=0;
        memset(vis,0,sizeof(vis));//将vis数组进行初始化为0
        vis[i]=1;//记录下已经访问位置
        dfs(0,i);
        ans=min(sum,ans);
    }
    cout<<ans;
}

广搜

#include <bits/stdc++.h>
using namespace std;
struct node{
    int val,step;//因为广搜我们要借助队列来进行递推操作 要记录步长
    int left,right,parent;
}t[105];
int sum,ans = INT_MAX,vis[105];
void bfs(int pos){
    vis[pos] = 1;
    queue<node> nodes;
    node tt = t[pos];
    tt.step = 0;//设置步长
    nodes.push(tt);
    while(!nodes.empty()){
        node front = nodes.front();
        sum+= front.val*front.step;
        nodes.pop();
//----------------------------错误演示-----------------------------
//        if(t[pos].parent && !vis[t[pos].parent]){//应判断头节点的父节点
//            vis[t[pos].parent] = 1;//标记父节点已被访问
//            node tt2 = t[t[pos].parent];
//            tt2.step = tt.step+1;//头节点步长+1
//            nodes.push(tt2);
//        }
//        if(t[pos].left && !vis[t[pos].left]){
//            vis[t[pos].left] = 1;
//            node tt2 = t[t[pos].left];
//            tt2.step = tt.step+1;
//            nodes.push(tt2);
//        }
//        if(t[pos].right && !vis[t[pos].right]){
//            vis[t[pos].right] = 1;//访问父节点
//            node tt2 = t[t[pos].right];
//            tt2.step = tt.step+1;
//            nodes.push(tt2);
//        }
        if(front.parent && !vis[front.parent]){//当前结点不为空 并且结点并没有被访问过
            vis[front.parent] = 1;//标记父节点已被访问
            node tt2 = t[front.parent];//对父节点进行数据拷贝
            tt2.step = front.step+1;//头节点的步长+1
            nodes.push(tt2);
        }
        if(front.left && !vis[front.left]){//当前结点不为空 并且结点并没有被访问过
            vis[front.left] = 1;
            node tt2 = t[front.left];
            tt2.step = front.step+1;
            nodes.push(tt2);
        }
        if(front.right && !vis[front.right]){//当前结点不为空 并且结点并没有被访问过
            vis[front.right] = 1;//访问父节点
            node tt2 = t[front.right];
            tt2.step = front.step+1;
            nodes.push(tt2);
        }
    }
}
int main(){
    int n,i;
    cin>>n;
    for(i=1;i<=n;i++){
        cin>>t[i].val>>t[i].left>>t[i].right;
        t[t[i].left].parent = i;
        t[t[i].right].parent = i;
    }
    for(i=1;i<=n;i++){
        sum=0;
        memset(vis,0,sizeof(vis));
        vis[i]=1;
        bfs(i);
        ans=min(ans,sum);
    }
    cout<<ans;
}

在提供的AC代码中,有关于图的深度优先索(DFS)和广度优先索(BFS)的实现方法。 在第一段代码中,是一个关于深度优先索的实现。该代码通过递归的方式来实现深度优先索。它使用了一个路径数组和一个标记数组来记录路径和访问状态。在每一次递归时,根据条件进行索,并在索完成后进行回溯操作。最终输出所有路径的结果。 在第二段代码中,是一个关于图的广度优先索的实现。该代码使用了一个队列来进行广度优先索。它使用了一个二维数组来表示图的状态和一个二维数组来记录访问状态。在索时,将起始点入队并标记为已访问,然后通过循环遍历队列中的元素,并根据条件进行索,并将符合条件的点入队并标记为已访问。最终返回从入口到出口的路径长度。 因此,根据提供的AC代码,可以实现图的深度优先索和广度优先算法。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [【C++】数据结构之深搜+广 经典题型](https://blog.csdn.net/weixin_64967734/article/details/124994451)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值