<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      【數據結構機試】樹

      存儲 & 訪問

      一般的樹

      vector<int> v[N];
      
      void dfs(int u) {
        for(auto x : v[u]) {
          ...
          dfs(x);
        }
      }
      

      二叉樹

      int L[N], R[N];  // 表示左右兒子的值分別是多少
      

      至于編號,結點 \(i\) 的左兒子 \(2i\),右兒子 \(2i+1\)

      樹的遍歷

      一般的數

      分為先根(先訪問根,后訪問兒子)、后根(先訪問兒子,后訪問根)。

      二叉樹

      先序遍歷(根左右)、中序遍歷(左根右)、后序遍歷(左右根)。

      例1
      PTA 1119 Pre- and Post-order Traversals

      題意

      給你先序和后序遍歷序列,判斷二叉樹形態是否唯一。

      解答

      首先知道先序的構成:序列第一個數是根,然后依次是根的左子樹和右子樹,根在后序序列中位于最后一個;
      先序第二個元素,是根的左兒子(除非根沒有左兒子,那么是根的右兒子);
      我們可以找到在后序序列中 先序第二個元素的位置 \(p\),在先序序列中,從 \(p-1\) 到正數第二個,這些都是根的左子樹, \(p + 1\) 到先序最末尾,這些都是根的右子樹,我們由此遞歸建樹。

      形態不唯一的情況:對某棵子樹的根來說,它只有左兒子無右兒子 或者 只有右兒子無左兒子,那么無論它到底有的是哪個兒子,你會發現,這兩種情況對應的先序和后序序列一樣,即無法判斷,此時就是不唯一的

      code
      點擊查看代碼
      #include<bits/stdc++.h>
      #define int long long
      using namespace std;
      const int N = 3000 + 10;
      int n, pre[N], post[N], tem[N];
      int rt, L[N], R[N];
      map<int, int> mp, Map;
      int dfn, ans[N];
      bool f = 1;
      
      int solve(int l1, int r1, int l2, int r2) {
          if(l1 > r1 || l2 > r2) return 0;
          if(l1 == r1) return pre[l1];
          int now_rt = pre[l1];
          int now_l = pre[l1 + 1], pos = mp[now_l];
          int cnt_l = pos - l2 + 1, cnt_r = r2 - pos - 1;
          L[now_rt] = solve(l1 + 1, l1 + cnt_l, l2, l2 + cnt_l - 1);
          R[now_rt] = solve(l1 + cnt_l + 1, r1, l2 + cnt_l, r2 - 1);
          if(f && (!L[now_rt] || !R[now_rt]) && (L[now_rt] || R[now_rt])) f = 0;
          return pre[l1];
      }
      
      void dfs(int rt) {
          if(L[rt]) dfs(L[rt]);
          ans[++dfn] = rt;
          if(R[rt]) dfs(R[rt]);
      }
      
      signed main(){
          ios::sync_with_stdio(false);
          cin >> n;
          for(int i = 1; i <= n; i++) cin >> pre[i], tem[i] = pre[i];
          for(int i = 1; i <= n; i++) cin >> post[i];
          sort(tem + 1, tem + n + 1);
          for(int i = 1; i <= n; i++) {
              int x = pre[i];
              pre[i] = lower_bound(tem + 1, tem + n + 1, pre[i]) - tem;
              Map[pre[i]] = x;
              post[i] = lower_bound(tem + 1, tem + n + 1, post[i]) - tem;
              mp[post[i]] = i;
          }
          if(n == 1) {
              cout << "Yes" << '\n';
              cout << Map[pre[1]] << endl;
              return 0;
          }
          rt = solve(1, n, 1, n);
          dfs(rt);
          cout << (f ? "Yes" : "No") << endl;
          for(int i = 1; i <= dfn; i++) {
              ans[i] = Map[ans[i]];
              if(i == 1) cout << ans[i];
              else cout << ' ' << ans[i];
          }cout << '\n';
      	return 0;
      } 
      
      

      LCA

      單次詢問 \(O(n)\) 復雜度的做法不再贅述。

      并查集

      當我們只關心結點之間有沒有關系時使用

      分享一個板子:

      點擊查看代碼
      //并查集模板 親戚 
      #include<cstdio>
      using namespace std;
      int father[5005];
      
      //路徑壓縮 
      int f(int x){
          return x == father[x] ? x : (father[x] = f(father[x]));
      }
      
      int add(int x,int y){ 
      	int fx=f(x);
      	int fy=f(y);
      	return father[fx]=fy;  //x.y無序,因為不是按樹的結構存儲,而是按集合 
      }
      
      int main(){
      	int n,m,p;
      	scanf("%d%d%d",&n,&m,&p);
      	for(int i=1;i<=n;i++) father[i]=i;
      	for(int i=1;i<=m;i++){
      		int x,y;
      		scanf("%d%d",&x,&y);
      		if(f(x)!=f(y)){
      			add(x,y);
      		}
      	}
      	for(int i=1;i<=p;i++){
      		int x,y;
      		scanf("%d%d",&x,&y);
      		if(f(x)==f(y)){
      			puts("Yes");
      		}
      		else puts("No");
      	}
      	return 0;
      }
      
      

      例1
      PTA 1034 Head of a Gang

      題意

      \(m\) 通電話,給出通話雙方和時長(注意,兩人之間可能有多次通話),通話過的人屬于同一幫人。找到 人數>=3 且 通話總時間(幫派中每兩人之間)>=K 的幫派的人數和首領(和其他人通話最長的)

      解答

      并查集維護,注意要字符串轉數字編號,累加兩人通話總時間

      code
      點擊查看代碼
      #include<bits/stdc++.h>
      #define ll long long
      using namespace std;
      const int N = 2000 + 10;
      int m, k;
      map<string, int> mp;
      string a, b;
      int tem[N], dfn, ori[N];
      struct node{
          int u, v, t;
      }peo[N];
      int g[N][N]; 
      bool vis[N][N];
      int fa[N], sz[N], cnt[N];
      vector<int> v[N];
      int ans[N], id[N];
      vector<int> prin;
      
      inline int f(int x){
          return x == fa[x] ? x : (fa[x] = f(fa[x]));
      }
      
      void add(int u, int v) {
          int w = g[u][v];
          u = f(u); v = f(v);
          if(u != v) {
              fa[u] = v;
              sz[v] += sz[u] + w;
              cnt[v] += cnt[u];
          }
          else {
              sz[u] += w;
          }
          return;
      }
      
      int main(){
          // ios::sync_with_stdio(false);
          cin >> m >> k;
          for(int i = 1; i <= m; i++) {
              cin >> a >> b;
              if(!mp[a]) mp[a] = (a[0] - 'A') * 26 * 26 + (a[1] - 'A') * 26 + (a[2] - 'A') + 1, tem[++dfn] = mp[a];
              if(!mp[b]) mp[b] = (b[0] - 'A') * 26 * 26 + (b[1] - 'A') * 26 + (b[2] - 'A') + 1, tem[++dfn] = mp[b];
              peo[i].u = mp[a]; peo[i].v = mp[b]; cin >> peo[i].t;
          }
          // cout << "dfn: " << dfn << endl;
          sort(tem + 1, tem + dfn + 1);
          for(int i = 1; i <= m; i++) {
              int x = peo[i].u;
              peo[i].u = lower_bound(tem + 1, tem + dfn + 1, peo[i].u) - tem;
              ori[peo[i].u] = x; 
      
              x = peo[i].v;
              peo[i].v = lower_bound(tem + 1, tem + dfn + 1, peo[i].v) - tem;
              ori[peo[i].v] = x;
              // cout << peo[i].u << ' ' << peo[i].v << endl;  ////
              g[peo[i].u][peo[i].v] += peo[i].t; g[peo[i].v][peo[i].u] += peo[i].t;
          }
          for(int i = 1; i <= dfn; i++) fa[i] = i, cnt[i] = 1, sz[i] = 0;
          for(int i = 1; i <= m; i++) {
              if(vis[peo[i].u][peo[i].v]) continue;
              vis[peo[i].u][peo[i].v] = vis[peo[i].v][peo[i].u] = 1;
              add(peo[i].u, peo[i].v);
              // cout << peo[i].u << ' ' << peo[i].v << ' ' << g[peo[i].u][peo[i].v] << endl;  ////
          }
          set<int> st;
          for(int i = 1; i <= dfn; i++) {
              int p = f(i);
              // cout << p << ' ' << cnt[p] << ' ' << sz[p] << endl;
              if(cnt[p] > 2 && sz[p] > k) st.insert(p), v[p].push_back(i);
          }
          cout << st.size() << endl;
          if(st.empty()) return 0;
      
          memset(ans, -1, sizeof(ans));
          for(auto i : st) {   // i: predecessor
              for(auto x : v[i]) {   // x: son
                  int res = 0;
                  for(int j = 1; j <= dfn; j++) {
                      res += g[x][j];
                  }
                  if(res > ans[i]) ans[i] = res, id[i] = x;
              }
              prin.push_back(id[i]);
          }
          sort(prin.begin(), prin.end());
          for(auto i : prin) {
              int tmp = ori[i] - 1;
              string s;
              s += (char)(tmp / (26 * 26) + 'A'); tmp %= (26 * 26);
              s += (char)(tmp / (26) + 'A'); tmp %= (26);
              s += (char)(tmp + 'A');
              cout << s << ' ' << cnt[f(i)] << endl;
          }
      	return 0;
      } 
      
      

      AVL樹(平衡二叉樹)

      posted @ 2023-08-27 13:53  starlightlmy  閱讀(41)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 小鲜肉自慰网站| 26uuu另类亚洲欧美日本| 色99久久久久高潮综合影院| 精品人妻午夜福利一区二区| 久久99精品久久久久麻豆 | 精品黄色av一区二区三区| 国产成人午夜福利在线小电影| 欧美私人情侣网站| 精品在免费线中文字幕久久| 国产成人午夜精品影院| 卫辉市| 国产高清亚洲一区亚洲二区| 色偷偷www.8888在线观看| 97人人添人人澡人人澡人人澡 | 亚洲精品一区二区动漫| 免费A级毛片无码A∨蜜芽试看| 日韩精品一区二区高清视频| 女子spa高潮呻吟抽搐| 四虎影视一区二区精品| 无码人妻精品一区二区三区东京热 | 免费无码黄十八禁网站| 国产午夜福利在线机视频 | 起碰免费公开97在线视频| 日韩精品一区二区蜜臀av| 97久久精品人人澡人人爽| 国产成人精品亚洲资源| 99热这里有精品| 日韩一区二区大尺度在线| 西宁市| 又黄又刺激又黄又舒服| 亚洲熟妇色xxxxx欧美老妇| 中文丰满岳乱妇在线观看| 亚洲免费视频一区二区三区| 人妻出轨av中文字幕| 一本色道久久东京热| 国内女人喷潮完整视频| 日本xxxx色视频在线播放| 亚洲午夜成人精品电影在线观看| 久久国产一区二区三区| 亚洲国产成人久久综合同性| 不卡国产一区二区三区|