醫院設定
阿新 • • 發佈: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],<[i],&rt[i]); } HSrecur(1); dsum(1,mind); printf("%d\n",mind); return 0; }
二、 然後就是我瞭解了floyed演算法(不過在探索floyed的過程中,我也學會了迪克斯特拉演算法和廣搜確定單源最短路徑問題)
BFS to find the shortest routine
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; }