医院设置

时间:2021-09-24
本文章向大家介绍医院设置,主要包括医院设置使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

医院设置
首先声明一点(最重要的一点):

题目原句是“接下来的n行,每一行描述了一个结点的情况”,似乎的
确表示每一行是按顺序输入每个节点的信息,而我由于之前的题目都
是此行表示是否有左右子树,然后接下来就是分别递归的输入左右子
树,所以我就按照这个思路进行读取,不过不太显然的错了,题目的
测试样例5个只有一个错了,让我始终没有怀疑这种读取方式,反而
在寻找是否有特殊情况没有考虑到,最终经过学习了floyed算法并
看了题解才发现自己的读取思路错了!!!!!!!

一、 最开始我的思路是,算出来根节点对应的路程和,然后根据各节点周围的数量关系来算出各个节点的路程和(不太敢确定,但似乎时间复杂度是O(n)?!,但无疑空间复杂度非常大。。。)
code :

//https://www.luogu.com.cn/problem/P1364
// This problem can be tried to use non-recur
#include<iostream>
#define LOCAL
using namespace std;
// int n;
int lt[105]={0},rt[105]={0},tn[105]={0};
int ln[105]={0},rn[105]={0},pn[105]={0};        //ln : the number of node in the left tree . Others by analogy (p-->parent)
int mind=0;                           //when hospital is set in root, the sum of distance
// int HSrecur(int id,int lv){
//     int idl,idr;
//     scanf("%d %d %d",&tn[id],&idl,&idr);
//     mind+=tn[id]*(lv-1);
//     if (idl) {
//         lt[id]=idl; 
//         // cout<<idl<<endl;
//         ln[id]=HSrecur(idl,lv+1);
//         // printf("%d\n",ln[id]);
//     }
//     if (idr) {
//         rt[id]=idr;
//         // cout<<idr<<endl;
//         rn[id]=HSrecur(idr,lv+1);
//         // printf("%d\n",rn[id]);
//     }
//     return ln[id]+rn[id]+tn[id];
// }
int HSrecur(int id){
    if (lt[id]==0 && rt[id]==0) return tn[id];
    if (lt[id]) ln[id]=HSrecur(lt[id]);
    if (rt[id]) rn[id]=HSrecur(rt[id]);
    mind+=ln[id]+rn[id];
    return ln[id]+rn[id]+tn[id];
}


void dsum(int id,int hsf){
    int sum;
    if (id!=1) {sum=hsf+pn[id]-ln[id]-rn[id]-tn[id]; if (sum<mind) mind=sum;}
    else sum=hsf;
    // printf("%d\n",sum);
    if (lt[id]){ 
        pn[lt[id]]=pn[id]+rn[id]+tn[id];
        // cout<<lt[id]<<endl;
        dsum(lt[id],sum);
    }
    if (rt[id]) {
        pn[rt[id]]=pn[id]+ln[id]+tn[id];
        // cout<<rt[id]<<endl;
        dsum(rt[id],sum);
    }
}

int main(){
    #ifdef LOCAL
    freopen("input.txt","r",stdin);
    #endif
    int n;
    scanf("%d\n",&n);
    for (int i=1;i<=n;i++){
        scanf("%d %d %d",&tn[i],&lt[i],&rt[i]);
    }
    HSrecur(1);
    dsum(1,mind);
    printf("%d\n",mind);
    return 0;
}

二、 然后就是我了解了floyed算法(不过在探索floyed的过程中,我也学会了迪克斯特拉算法和广搜确定单源最短路径问题)

BFS to find the shortest routine

floyed algorithm

prove floyed algorithm

code:

#include<iostream>
#define LOCAL
using namespace std;
int adjacent_matrix[101][101];
int record_value[101]={0};
const unsigned int INF_INT=0x3f3f3f3f;
// void init_matrix(int id){
//     int idl,idr;
//     scanf("%d %d %d",&record_value[id],&idl,&idr);
//     adjacent_matrix[id][id]=0;
//     if (idl){
//         adjacent_matrix[id][idl]=1;
//         adjacent_matrix[idl][id]=1;
//         init_matrix(idl);
//     }
//     if (idr){
//         adjacent_matrix[id][idr]=1;
//         adjacent_matrix[idr][id]=1;
//         init_matrix(idr);
//     }
// }
void floyed(int mtx[101][101],int n){   //无论多少维数组,第一维可以省略,但第二维就不可以省略,这是由编译器的寻址方式决定的
    for (int i=1;i<=n;++i){
        for (int p=1;p<=n;++p){
            if (p==i) continue;
            for (int q=1;q<=n;++q){
                // mtx[p][q]=mtx[p][q]<(mtx[p][i]+mtx[i][q])?mtx[p][q]:(mtx[p][i]+mtx[i][q]);
                if (p!=q && q!=i && mtx[p][q]>(mtx[p][i]+mtx[i][q])) mtx[p][q]=(mtx[p][i]+mtx[i][q]);
            }
        }
    }
}
int main(){
    #ifdef LOCAL
    freopen("input.txt","r",stdin);
    #endif
    int N;
    scanf("%d",&N);
    for (int i=0;i<=101;++i){
        for (int j=0;j<=101;++j){
            adjacent_matrix[i][j]=INF_INT;
        }
    }
    for (int i=1;i<=N;++i){
        int l,r;
        adjacent_matrix[i][i]=0;
        scanf("%d %d %d",&record_value[i],&l,&r);
        if (l) adjacent_matrix[i][l]=adjacent_matrix[l][i]=1;
        if (r) adjacent_matrix[i][r]=adjacent_matrix[r][i]=1;
    }
    // init_matrix(1);
    floyed(adjacent_matrix,N);
    int minhs=INF_INT;
    for (int i=1;i<=N;++i){
        int sum=0;
        for (int j=1;j<=N;++j){
            sum+=adjacent_matrix[i][j]*record_value[j];
        }
        // printf("%d\n",sum);
        if (sum<minhs) minhs=sum;
    }
    printf("%d\n",minhs);
    return 0;
}

原文地址:https://www.cnblogs.com/DarrenLU/p/15328664.html