RedSenior

导航

21-24贪心算法

21贪心算法

22活动安排问题

究其本质,是一个最大不相交区间问题,要写出具体数量以及的几个

点击查看代码
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
const int N  = 100010;
//保存区间
vector<vector<int>> a(N,vector<int>(2,0));
int n;

int main()
{
    cin >> n;
    //读入区间
    for(int i = 0; i< n; i++)
    {
        int l, r;
        cin >> l >> r;
        a[i][0] = l;
        a[i][1] = r;
    }
    // 按右端点排序
    sort(a.begin(), a.begin() + n, [](vector<int> &a, vector<int> &b){return a[1] < b[1];});
    // res 保存答案,end 是当前选的点
    int res = 0, end = -1e9 - 10;
    // 遍历区间
    for(int i = 0; i < n; i++)
    {
        // 如果当前选的点覆盖了该区间,则跳过
        if(end >= a[i][0] && end <= a[i][1]) 
            continue;
        else
        {
            // 选的点+1, 选的点更新为区间右端点
            res++;
            end = a[i][1];
        }
    }
    cout << res;
    return 0;
}

23最小生成树

点击查看代码
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;

const int N = 510;
int g[N][N];//存储图
int dt[N];//存储各个节点到生成树的距离
int st[N];//节点是否被加入到生成树中
int pre[N];//节点的前去节点
int n, m;//n 个节点,m 条边

void prim()
{
    memset(dt,0x3f, sizeof(dt));//初始化距离数组为一个很大的数(10亿左右)
    int res= 0;
    dt[1] = 0;//从 1 号节点开始生成 
    for(int i = 0; i < n; i++)//每次循环选出一个点加入到生成树
    {
        int t = -1;
        for(int j = 1; j <= n; j++)//每个节点一次判断
        {
            if(!st[j] && (t == -1 || dt[j] < dt[t]))//如果没有在树中,且到树的距离最短,则选择该点
                t = j;
        }

        //2022.6.1 发现测试用例加强后,需要判断孤立点了
        //如果孤立点,直返输出不能,然后退出
        if(dt[t] == 0x3f3f3f3f) {
            cout << "impossible";
            return;
        }


        st[t] = 1;// 选择该点
        res += dt[t];
        for(int i = 1; i <= n; i++)//更新生成树外的点到生成树的距离
        {
            if(dt[i] > g[t][i] && !st[i])//从 t 到节点 i 的距离小于原来距离,则更新。
            {
                dt[i] = g[t][i];//更新距离
                pre[i] = t;//从 t 到 i 的距离更短,i 的前驱变为 t.
            }
        }
    }

    cout << res;

}

void getPath()//输出各个边
{
    for(int i = n; i > 1; i--)//n 个节点,所以有 n-1 条边。

    {
        cout << i <<" " << pre[i] << " "<< endl;// i 是节点编号,pre[i] 是 i 节点的前驱节点。他们构成一条边。
    }
}

int main()
{
    memset(g, 0x3f, sizeof(g));//各个点之间的距离初始化成很大的数
    cin >> n >> m;//输入节点数和边数
    while(m --)
    {
        int a, b, w;
        cin >> a >> b >> w;//输出边的两个顶点和权重
        g[a][b] = g[b][a] = min(g[a][b],w);//存储权重
    }

    prim();//求最下生成树
    //getPath();//输出路径
    return 0;
}

24哈夫曼编码


posted on 2024-12-01 23:18  RedLouie  阅读(5)  评论(0编辑  收藏  举报