最短路径(c++)

1 需求分析

假设要在足够多的会场里安排一批活动,并希望使用尽可能少的会场.设计一个有效的贪心算法进行安排.(这个问题实际上是著名的图着色问题.若将每一个活动作为图的一个顶点,不相容活动间用边相连.使相连顶点着不同颜色的最少着色数,相应于要找最少会场数.)

2 概要设计

主函数
在这里插入图片描述
贪心算法
在这里插入图片描述

3 详细设计

首先定义一个结构体数组,用来存储每个活动的开始时间和结束时间

struct node
{
    int x, y;        //x为活动开始时间,y为活动结束时间
}P[MAX];

然后设计一个排序算法,按升序排列活动结束时间

bool cmp(node a, node b)   
{
    return a.y < b.y;       //使a.y<b.y
}
sort(P, P + n, cmp);        //按升序排列活动结束时间

然后通过for循环录入活动开始时间活动结束时间

 for (int i = 0; i < n; ++ i)       
 {
	scanf("%d%d", &a,&b);
   P[i].x = a;              //活动开始时间
   P[i].y = b;              //活动结束时间
  }

贪心算法

for (int i = 0; i < n; ++ i)   
    {
        if (P[i].x > temp)        //若活动开始时间大于活动结束时间则把下一个活动结束时间赋给temp,并增加会场数 
        {
            temp = P[i].y;
            ++ ans;
         }
    }

4复杂度分析

sort(P, P + n, cmp)排序,时间复杂度为log2n
贪心算法:时间复杂度为nlog n
排序时冒泡排序时间复杂度为O(n2)
经百度后sort排序时间复杂度为log2n故采用sort排序

5测试

4 测试
活动数:5
开始 结束
12 15
18 27
26 55
1 8
2 9
在这里插入图片描述

源代码

#include <iostream>
#include <algorithm>
using namespace std;
const int MAX = 1e6 + 10;
int a, b, ans = 1, temp, n;
struct node
{
    int x, y;
} P[MAX];
bool cmp(node a, node b)
{
    return a.y < b.y;
}
int main()
{
    scanf("%d", &n);
    for (int i = 0; i < n; ++ i)
    {
        scanf("%d %d", &a,&b);
        P[i].x = a,
        P[i].y = b;
    }
    sort(P, P + n, cmp);
    temp = P[0].y;
    for (int i = 0; i < n; ++ i)
    {
        if (P[i].x > temp)
        {
            temp = P[i].y;
            ++ ans;
        }
    }
    printf("%d\n", ans);
    return 0;
}

以下是使用 Dijkstra 算法求解最短路径C++ 代码示例: ```c++ #include <iostream> #include <vector> #include <queue> #include <climits> using namespace std; #define MAX_N 1000 // 最大顶点数 struct Edge { int to; // 边的目标顶点 int cost; // 边权重 }; vector<Edge> g[MAX_N]; // 图的邻接表表示 int d[MAX_N]; // 存储起点到各顶点的最短距离 bool used[MAX_N]; // 最短距离是否已经确定 void dijkstra(int s) { // 初始化 fill(d, d + MAX_N, INT_MAX); fill(used, used + MAX_N, false); d[s] = 0; // 创建小根堆,存储未确定最短距离的顶点 priority_queue<pair<int, int>, vector<pair<int, int> >, greater<pair<int, int> > > q; // 把起点加入小根堆 q.push(make_pair(0, s)); // 计算最短距离 while (!q.empty()) { // 取出小根堆中最小距离的顶点 pair<int, int> p = q.top(); q.pop(); int v = p.second; // 如果最短距离已经确定,就跳过 if (used[v]) continue; // 标记最短距离已经确定 used[v] = true; // 更新相邻顶点的最短距离 for (int i = 0; i < g[v].size(); i++) { Edge e = g[v][i]; if (d[e.to] > d[v] + e.cost) { d[e.to] = d[v] + e.cost; q.push(make_pair(d[e.to], e.to)); } } } } int main() { // 读入顶点数、边数和起点编号 int n, m, s; cin >> n >> m >> s; // 读入边 for (int i = 0; i < m; i++) { int u, v, c; cin >> u >> v >> c; g[u].push_back(Edge{v, c}); } // 计算最短距离 dijkstra(s); // 输出结果 for (int i = 0; i < n; i++) { if (d[i] != INT_MAX) { cout << d[i] << endl; } else { cout << "INF" << endl; } } return 0; } ``` 其中,`g` 表示图的邻接表,`d` 表示起点到各顶点的最短距离,`used` 表示最短距离是否已经确定。函数 `dijkstra` 是求解最短路径的核心函数,它使用小根堆来存储未确定最短距离的顶点,并逐步计算出最短距离。在主函数中,先读入顶点数、边数和起点编号,然后读入边,最后调用 `dijkstra` 函数计算最短距离并输出结果。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值