当前位置: 首页 > news >正文

10.17 枚举中间|图论

 

 

lc2867

先标记出非质数,再构建树的结构

(DFS)统计每个由非质数组成的连通块大小

计算满足恰好含一个质数节点的合法路径数量。

const int MX = 1e5;
bool np[MX + 1]; // 质数=false 非质数=true
int init = []() {
    np[1] = true;
    for (int i = 2; i * i <= MX; i++) {
        if (!np[i]) {
            for (int j = i * i; j <= MX; j += i) {
                np[j] = true;
            }
        }
    }
    return 0;
}();

 

class Solution {
public:
    long long countPaths(int n, vector<vector<int>> &edges) {
        vector<vector<int>> g(n + 1);
        for (auto &e: edges) {
            int x = e[0], y = e[1];
            g[x].push_back(y);
            g[y].push_back(x);
        }

        vector<int> size(n + 1);
        vector<int> nodes;
        function<void(int, int)> dfs = [&](int x, int fa) {
            nodes.push_back(x);
            for (int y: g[x]) {
                if (y != fa && np[y]) {
                    dfs(y, x);
                }
            }
        };

        long long ans = 0;
        for (int x = 1; x <= n; x++) {
            if (np[x]) continue; // 跳过非质数
            int sum = 0;
            for (int y: g[x]) { // 质数 x 把这棵树分成了若干个连通块
                if (!np[y]) continue;
                if (size[y] == 0) { // 尚未计算过
                    nodes.clear();
                    dfs(y, -1); // 遍历 y 所在连通块,在不经过质数的前提下,统计有多少个非质数
                    for (int z: nodes) {
                        size[z] = nodes.size();
                    }
                }
                // 这 size[y] 个非质数与之前遍历到的 sum 个非质数,两两之间的路径只包含质数 x
                ans += (long long) size[y] * sum;
                sum += size[y];
            }
            ans += sum; // 从 x 出发的路径
        }
        return ans;
    }
};

 

 

lc2242

先构建图,把每个点连接的点按分数排序并保留前3个

if (vs.size() > 3) 
                nth_element(vs.begin(), vs.begin() + 3, vs.end());
    vs.resize(3);

然后枚举中间边(x-y)   a-x-y-b

找边两端点各自连接的点中合适的(除环),计算能组成的最大得分

if (a != y && b != x && a != b)
                  ans = max(ans, -score_a + scores[x] + scores[y] - score_b);

 

返回最大得分(没有符合的就返回-1)

 class Solution {
public:
    int maximumScore(vector<int> &scores, vector<vector<int>> &edges)

{
        int n = scores.size();
        vector<vector<pair<int, int>>> g(n);
        for (auto &e : edges) {
            int x = e[0], y = e[1];
            g[x].emplace_back(-scores[y], y);
            g[y].emplace_back(-scores[x], x);
        }
        for (auto &vs : g)
            if (vs.size() > 3) {
                nth_element(vs.begin(), vs.begin() + 3, vs.end());
                vs.resize(3);
            }

        int ans = -1;
        for (auto &e : edges) {
            int x = e[0], y = e[1];
            for (auto &[score_a, a] : g[x])
                for (auto &[score_b, b] : g[y])
                    if (a != y && b != x && a != b)
                        ans = max(ans, -score_a + scores[x] + scores[y] - score_b);
        }
        return ans;
    }
};


为了对图中每个节点,只保留与它相连的、分数最大的前三个节点

if (vs.size() > 3) 
         nth_element(vs.begin(), vs.begin() + 3, vs.end());
    vs.resize(3);
 
- 首先遍历图  g  中的每个节点的邻接列表  vs 。
- 如果邻接列表的长度超过3,就使用  nth_element  函数,把第3大的元素放到  vs.begin() + 3  的位置,这样前3个元素就是最大的三个。
- 然后通过  vs.resize(3) ,将邻接列表的长度调整为3,从而只保留分数最大的前三个相邻节点


思考枚举点还是边
将问题放小,假设三个点怎么办
三个点则枚举中间点,再枚举两边最优
优化,贪心每次选最大的权值
则一个点最多往外连三个点

写的时候可以借助提供的边一下子确定两个点,灵活运用点和边的关系
(这样就不用写四个循环和一堆判断了)

 

 

lc2874

预处理+单调性

class Solution {
public:
    long long maximumTripletValue(vector<int>& nums) 
    {
        //dan diao xin
        int n=nums.size();
        vector<int> max_left(n,0);
        vector<int> max_right(n,0);
        long long ret=LONG_MIN;
        
        for(int i=1;i<n-1;i++)
        {
            max_left[i]=max(max_left[i-1],nums[i-1]);
        }
        
        for(int i=n-2;i>0;i--)
        {
            max_right[i]=max(max_right[i+1],nums[i+1]);
        }
        
        for(int i=1;i<n-1;i++)
        {
            ret=max(ret,(long long)(max_left[i]-nums[i])*max_right[i]);
        }
        return ret<0?0:ret;
    }
};

 

lc2909

枚举j,记忆mn i &预处理mn k

class Solution {

public:

    int minimumSum(vector<int>& nums) 

    {

        int n=nums.size();

        int mnl=nums[0];

        vector<int> pmn(n,INT_MAX);

        pmn[n-1]=nums[n-1];

        for(int a=n-2;a>=0;a--)

        {

            pmn[a]=min(pmn[a+1],nums[a+1]);

            //not include 0

        }

        int ret=INT_MAX;

        for(int j=1;j<n;j++)

        {

            if(mnl<nums[j] && pmn[j]<nums[j])

            {

    ret=min(mnl+nums[j]+pmn[j],ret);

            }

            mnl=min(mnl,nums[j]);

        }

        return ret==INT_MAX?-1:ret;

    }

};

 

lc447

hash

遍历每个点,计算它与其他点的距离

用hash统计各距离出现次数

再根据次数算出能组成的回旋镖数量并累加,最终得到所有回旋镖的总数

 class Solution {

public:

    int numberOfBoomerangs(vector<vector<int>>& points) {

        int ans = 0;

        unordered_map<int, int> cnt;

        for (auto& p1 : points) {

            cnt.clear();

            for (auto& p2 : points) {

                int d2 = (p1[0] - p2[0]) * (p1[0] - p2[0]) + (p1[1] - p2[1]) * (p1[1] - p2[1]);

                ans += cnt[d2]++ * 2;

            }

        }

        return ans;

    }

};

 

http://www.dtcms.com/a/495788.html

相关文章:

  • if条件语句 三目运算符 汇编分析
  • LeetCode 401 - 二进制手表
  • 【Leetcodenowcode数据结构】顺序表的应用
  • 软考高项论文考试攻略2:从备考到写作的专业指南
  • vue2和vue3函数式调用组件学习记录
  • 廊坊市固安县建设局网站中小企业网络设计论文
  • 3D打印技术在金属材料上的应用现状
  • 网站数据库丢失注册公司网站需要什么资料
  • 重生之我在大学自学鸿蒙开发第九天-《分布式流转》
  • 做手机网站公司wordpress萌主题下载
  • 【Android15快速自定义与集成音效实战课】:正式上线了(二百六十二)
  • 数字化时代,企业应该如何看待商业智能BI
  • 算法---队列+宽搜
  • 解锁分布式唯一 ID:技术、实践与最佳方案
  • 检察院门户网站建设方案网站建设a2345
  • GB200 NVL72超节点深度解析:架构、生态与产业格局
  • 课程网站的设计做网站被骗去哪投诉
  • YOLO家族进化史:从V1到V3的跨越
  • Lipschitz连续及其常量
  • 个人做网站公司宁波趋势信息科技有限公司
  • 安装好采集侠网站地图后在哪里查看网站地图精准粉丝引流推广
  • 外贸soho怎么建网站网站的分辨率
  • 子序列问题
  • 多模态大模型Ovis2.5核心技术改进点、训练方法
  • 建网站步骤ps临摹图片做网站的图片犯法吗
  • 网站建设服务的具体条件烟台企业网站开发
  • 如何做分公司网站wordpress数据库版本
  • DeviceNet 转 MODBUS TCP:倍福 CX 系列 PLC 与 MES 系统在 SMT 回流焊温度曲线监控的通讯配置案例
  • 湛江企业自助建站全国网站建设公司实力排名
  • Redux和@reduxjs/toolkit同时在Next.js项目中使用