zoukankan      html  css  js  c++  java
  • a_lc_统计子树中城市之间最大距离(枚举子集 + floyd / 2*dfs 求直径)

    返回一个大小为 n-1 的数组,其中第 d 个元素(下标从 1 开始)是城市间 最大距离 恰好等于 d 的子树数目。
    2 <= n <= 15

    思路
    这题求解的方法会有很多,但共同点都是枚举子集:

    • 检测子集的连通性+2*dfs求每个子集的直径
    • floyd求每个点的最长距离

    floyd求出n个点之间最短距离,枚举所有子集,对于每一个子集都去检查连通性,并求出两点之间的最长距离

    const int N=20, inf=0x3f3f3f3f;
    class Solution {
    public:
        int dp[N][N], sta[N][N];
        vector<int> countSubgraphsForEachDiameter(int n, vector<vector<int>>& es) {
            for (int i=0; i<n; i++)
            for (int j=0; j<n; j++)
                dp[i][j]=i==j ? 0:inf;
            for (auto& e : es) {
                int a=e[0]-1, b=e[1]-1;
                sta[a][b]=sta[b][a]=1;
                dp[a][b]=dp[b][a]=1;
            }
            for (int k=0; k<n; k++)
            for (int i=0; i<n; i++)
            for (int j=0; j<n; j++) if (i!=j && dp[i][k]!=inf && dp[k][j]!=inf) {
                dp[i][j]=min(dp[i][j], dp[i][k]+dp[k][j]);
            }
            int tot=1<<n, maxD=1;
            vector<int> ans(n-1, 0);
            for (int st=1; st<tot; st++) {
                vector<int> v;
                for (int j=0; j<n; j++) if (st&(1<<j))
                    v.push_back(j);
                if (v.size()<=1) continue;
                int m=v.size(), edge=0, maxD=0;
                for (int i=0; i<m-1; i++)
                for (int j=i+1; j<m; j++) {
                    if (sta[v[i]][v[j]]) edge++;
                    maxD=max(maxD, dp[v[i]][v[j]]);
                }
                if (edge==m-1) ans[maxD-1]++;
            }
            return ans;
        }
    };
    
  • 相关阅读:
    javascript重点笔记
    我的CSS架构
    排行榜妙用——CSS计数器
    回归基础从新认识——HTML+CSS
    前端开发工具(安装及常用技巧)——sublime text 3
    手机访问php环境移动端静态页面
    H5前端面试题及答案(2)
    H5前端面试题及答案(1)
    python笔记--学会使用Fiddler
    python进程/线程/协成
  • 原文地址:https://www.cnblogs.com/wdt1/p/13799666.html
Copyright © 2011-2022 走看看