1. 程式人生 > 其它 >醫院設定

醫院設定

醫院設定
首先宣告一點(最重要的一點):

題目原句是“接下來的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;
}