0x17 二叉堆

本文详细介绍了手写模板实现的堆操作,包括插入、查找最大值、删除等,并利用Huffman树解决最小化加权路径长度问题。通过具体例题展示了不同场景下算法的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

手写模板:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cmath>
 4 #include <cstring>
 5 #include <algorithm>
 6 #include <stack>
 7 using namespace std;
 8 const int INF=0x3f3f3f3f;
 9 const int maxn=100000+10;
10 int n;
11 int heap[maxn];
12 void up(int p) {
13     while (p>1) {
14         if (heap[p]>heap[p/2]) {
15             swap(heap[p], heap[p/2]);
16             p/=2;
17         }
18         else break;
19     }
20 }
21 void insert(int val) {
22     heap[++n]=val;
23     up(n);
24 }
25 int top() {
26     return heap[1];
27 }
28 void down(int p) {
29     int s=p*2;
30     while (s<=n) {
31         if (s<n&&heap[s]<heap[s+1]) s++;    //左右子节点取较大者
32         if (heap[p]<heap[s]) {
33             swap(heap[p], heap[s]);
34             p=s; s=p*2;
35         }
36         else break;
37     } 
38 }
39 void extract() {
40     heap[1]=heap[n--];
41     down(1);
42 }
43 void remove(int k) {
44     heap[k]=heap[n--];
45     up(k), down(k);
46 }
47 
48 int main() {
49     //freopen("a.txt", "r", stdin);
50     //freopen("a.out", "w", stdout);
51     scanf("%d", &n);
52     for (int i=1; i<=n; ++i) {
53         int x;
54         scanf("%d", &x);
55         insert(x);
56         printf("%d\n", top());
57     }
58     return 0;
59 }
View Code

STL:

#include <queue>
priority_queue<int> q;

【例题】POJ1456 Supermarket

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cmath>
 4 #include <cstring>
 5 #include <algorithm>
 6 #include <queue>
 7 using namespace std;
 8 const int INF=0x3f3f3f3f;
 9 const int maxn=100000+10;
10 int n;
11 struct node {
12     int p, d;
13 } a[maxn];
14 priority_queue<int, vector<int>, greater<int> > Q;
15 
16 bool cmp(node a, node b) {
17     return a.d<b.d;
18 }
19 
20 int main() {
21     //freopen("a.txt", "r", stdin);
22     //freopen("a.out", "w", stdout);
23     while (~scanf("%d", &n)) {
24         for (int i=1; i<=n; ++i)
25             scanf("%d%d", &a[i].p, &a[i].d);
26         sort(a+1, a+n+1, cmp);
27         Q.push(a[1].p);
28         for (int i=2; i<=n; ++i) {
29             int w=Q.top(), sz=Q.size();
30             if (a[i].d==sz && a[i].p>w) {
31                 Q.pop();
32                 Q.push(a[i].p);
33             }
34             else if (a[i].d>sz) {
35                 Q.push(a[i].p);
36             }
37         }
38         int ans=0;
39         while (!Q.empty()) {
40             ans+=Q.top();
41             Q.pop();
42         }
43         printf("%d\n", ans);
44     }
45     return 0;
46 }
View Code

【例题】POJ2442 Sequence

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cmath>
 4 #include <cstring>
 5 #include <algorithm>
 6 #include <queue>
 7 using namespace std;
 8 const int INF=0x3f3f3f3f;
 9 const int maxn=2000+10;
10 const int maxm=100+10;
11 int n, m;
12 int A[maxm][maxn], f[maxn];
13 
14 struct node {
15     int p1, p2, i, j;
16     bool flag;
17     node() {};
18     node(int a, int b, int c, int d, int f) {
19         p1=a, p2=b, i=c, j=d, flag=f;
20     }
21 };
22 bool operator < (const node& a, const node& b) {
23     return (a.i+a.j)>(b.i+b.j);
24 }
25 
26 priority_queue <node> Q;
27 
28 void merge(int k) {
29     while (!Q.empty()) Q.pop();
30     Q.push(node(1, 1, f[1], A[k][1], 0));
31     int c[maxn], cnt=0;
32     while (!Q.empty()) {
33         node x=Q.top(); Q.pop();
34         c[++cnt]=x.i+x.j;
35         if (x.p2<m) Q.push(node(x.p1, x.p2+1, f[x.p1], A[k][x.p2+1], 1));
36         if (!x.flag && x.p1<m) Q.push(node(x.p1+1, x.p2, f[x.p1+1], A[k][x.p2], 0));
37         if (cnt==m) break;
38     }
39     for (int i=1; i<=m; ++i) f[i]=c[i];
40 }
41 
42 int main() {
43     //freopen("a.txt", "r", stdin);
44     //freopen("a.out", "w", stdout);
45     int T;
46     scanf("%d", &T);
47     while (T--) {
48         while (!Q.empty()) Q.pop();
49         scanf("%d%d", &n, &m);
50         for (int i=1; i<=n; ++i)
51             for (int j=1; j<=m; ++j)
52                 scanf("%d", &A[i][j]);
53         for (int i=1; i<=n; ++i) sort(A[i]+1, A[i]+m+1);
54         for (int i=1; i<=m; ++i) f[i]=A[1][i];
55         for (int i=2; i<=n; ++i) merge(i);
56         for (int i=1; i<=m; ++i) printf("%d ", f[i]);
57         puts("");
58     }
59     return 0;
60 }
View Code

Huffman树

构造一棵包含n个叶子节点的k叉树,其中第i个叶子节点带有权值Wi,要求最小化sigma(Wi*Li)。

【例题】CH1701/NOIP2004 合并果子

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cmath>
 4 #include <cstring>
 5 #include <algorithm>
 6 #include <queue>
 7 using namespace std;
 8 const int INF=0x3f3f3f3f;
 9 const int maxn=2000+10;
10 const int maxm=100+10;
11 int n;
12 priority_queue<int, vector<int>, greater<int> > Q;
13 
14 int main() {
15     //freopen("a.txt", "r", stdin);
16     //freopen("a.out", "w", stdout);
17     scanf("%d", &n);
18     for (int i=1; i<=n; ++i) {
19         int x;
20         scanf("%d", &x);
21         Q.push(x);
22     }
23     int ans=0;
24     while (Q.size()!=1) {
25         int x=Q.top(); Q.pop();
26         int y=Q.top(); Q.pop();
27         ans+=x+y;
28         Q.push(x+y);
29     }
30     printf("%d\n", ans);
31     return 0;
32 }
View Code

 

转载于:https://www.cnblogs.com/kkkstra/p/11118506.html

内容概要:该论文聚焦于T2WI核磁共振图像超分辨率问题,提出了一种利用T1WI模态作为辅助信息的跨模态解决方案。其主要贡献包括:提出基于高频信息约束的网络框架,通过主干特征提取分支和高频结构先验建模分支结合Transformer模块和注意力机制有效重建高频细节;设计渐进式特征匹配融合框架,采用多阶段相似特征匹配算法提高匹配鲁棒性;引入模型量化技术降低推理资源需求。实验结果表明,该方法不仅提高了超分辨率性能,还保持了图像质量。 适合人群:从事医学图像处理、计算机视觉领域的研究人员和工程师,尤其是对核磁共振图像超分辨率感兴趣的学者和技术开发者。 使用场景及目标:①适用于需要提升T2WI核磁共振图像分辨率的应用场景;②目标是通过跨模态信息融合提高图像质量,解决传统单模态方法难以克服的高频细节丢失问题;③为临床诊断提供更高质量的影像资料,帮助医生更准确地识别病灶。 其他说明:论文不仅提供了详细的网络架构设计与实现代码,还深入探讨了跨模态噪声的本质、高频信息约束的实现方式以及渐进式特征匹配的具体过程。此外,作者还对模型进行了量化处理,使得该方法可以在资源受限环境下高效运行。阅读时应重点关注论文中提到的技术创新点及其背后的原理,理解如何通过跨模态信息融合提升图像重建效果。
### 堆优化的Dijkstra算法C语言实现代码 堆优化版的Dijkstra算法通过使用最小堆(Min-Heap)来加速查找当前最短距离节点的过程。相比于朴素版本中每次扫描所有未访问节点来找最小值的方式,堆优化可以显著减少时间复杂度。 下面是基于二叉堆优化的Dijkstra算法的C语言实现: ```c #include <stdio.h> #include <stdlib.h> #define MAX_V 100001 #define INF 0x3f3f3f3f typedef struct { int to; int cost; } Edge; // 邻接表存储图 Edge edges[MAX_V]; int head[MAX_V], next_edge[MAX_V], edge_count = 0; void add_edge(int from, int to, int cost) { edges[edge_count].to = to; edges[edge_count].cost = cost; next_edge[edge_count] = head[from]; head[from] = edge_count++; } // 定义堆节点结构体 typedef struct Node { int id; int dist; } Node; // 最小堆比较函数 int cmp(const void* a, const void* b) { return ((Node*)a)->dist - ((Node*)b)->dist; } int main() { int n, m, s; // 节点数n,边数m,起点s scanf("%d%d%d", &n, &m, &s); for (int i = 0; i < m; ++i) { int u, v, w; scanf("%d%d%d", &u, &v, &w); add_edge(u, v, w); // 添加有向边 } int dist[n + 1]; for (int i = 1; i <= n; ++i) { dist[i] = INF; // 初始化距离为无穷大 } dist[s] = 0; Node heap[n + 1]; int heap_size = 0; // 初始将起点加入堆 heap[heap_size++] = (Node){s, 0}; while (heap_size > 0) { // 取出堆顶元素 qsort(heap, heap_size, sizeof(Node), cmp); Node top = heap[--heap_size]; int u = top.id; if (top.dist > dist[u]) continue; // 如果取出的距离不是最新,则跳过 // 松弛操作 for (int i = head[u]; i != -1; i = next_edge[i]) { int v = edges[i].to; int d = edges[i].cost; if (dist[v] > dist[u] + d) { dist[v] = dist[u] + d; heap[heap_size++] = (Node){v, dist[v]}; } } } // 输出结果 for (int i = 1; i <= n; ++i) { if (dist[i] == INF) { printf("-1\n"); // 不可达 } else { printf("%d\n", dist[i]); } } return 0; } ``` 此代码实现了带有堆优化的Dijkstra算法[^4]。程序首先读取输入数据构建图,并初始化距离数组 `dist` 和最小堆 `heap`。接着不断从堆中提取具有最小临时距离的节点进行扩展,直至堆为空为止。最后输出从起始节点到其余各节点间的最短路径长度。 --- ####
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值