【学习笔记】线段树优化建图
先开坑,有时间再说。
例题
CF786B Legacy
Code
点击查看代码
//线段树优化建图,从寒假一直咕到暑假 //之前觉得难得不行,现在看还是挺好理解的 #include<queue> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int MAXN = 2e6 + 10; int n, m, s, cnt, root_in, root_out; int head[MAXN]; long long dis[MAXN]; bool used[MAXN]; queue<int> q; struct Edge{ int to, next; long long dis; }e[MAXN]; inline void Add(int u, int v, long long w){ e[++cnt].to = v; e[cnt].dis = w; e[cnt].next = head[u]; head[u] = cnt; } struct Segment_Tree{ int tot; struct Tree{ int lson, rson; }tr[MAXN]; #define lson(x) tr[x].lson #define rson(x) tr[x].rson void Build_out(int &rt, int l, int r){ if(l == r){ rt = l; return; } rt = ++tot; int mid = (l + r) >> 1; Build_out(lson(rt), l, mid); Build_out(rson(rt), mid + 1, r); Add(rt, lson(rt), 0); Add(rt, rson(rt), 0); } void Build_in(int &rt, int l, int r){ if(l == r){ rt = l; return; } rt = ++tot; int mid = (l + r) >> 1; Build_in(lson(rt), l, mid); Build_in(rson(rt), mid + 1, r); Add(lson(rt), rt, 0); Add(rson(rt), rt, 0); } void Update_out(int rt, int l, int r, int L, int R, int u, int w){ if(L >= l && R <= r){ Add(u, rt, w); return; } int mid = (L + R) >> 1; if(l <= mid) Update_out(lson(rt), l, r, L, mid, u, w); if(r > mid) Update_out(rson(rt), l, r, mid + 1, R , u, w); } void Update_in(int rt, int l, int r, int L, int R, int v, int w){ if(L >= l && R <= r){ Add(rt, v, w); return; } int mid = (L + R) >> 1; if(l <= mid) Update_in(lson(rt), l, r, L, mid, v, w); if(r > mid) Update_in(rson(rt), l, r, mid + 1, R, v, w); } }S; void Spfa(int x){ memset(used, 0, sizeof(used)); memset(dis, 0x3f, sizeof(dis)); dis[x] = 0; q.push(x); used[x] = true; while(!q.empty()){ int k = q.front(); q.pop(); used[k] = false; for(register int i = head[k]; i; i = e[i].next){ int v = e[i].to; if(dis[v] > dis[k] + e[i].dis){ dis[v] = 1LL * dis[k] + e[i].dis; if(!used[v]){ q.push(v); used[v] = true; } } } } } inline long long read(){ long long x = 0, f = 1; char c = getchar(); while(c < '0' || c > '9'){ if(c == '-') f = -1; c = getchar(); } while(c >= '0' && c <= '9'){ x = (x << 1) + (x << 3) + (c ^ 48); c = getchar(); } return x * f; } int main(){ n = read(), m = read(), s = read(); S.tot = n; S.Build_out(root_out, 1, n); S.Build_in(root_in, 1, n); for(register int i = 1; i <= m; i++){ int opt; opt = read(); if(opt == 1){ int u, v, w; u = read(), v = read(), w = read(); Add(u, v, w); } else if(opt == 2){ int u, l, r, w; u = read(), l = read(), r = read(), w = read(); S.Update_out(root_out, l, r, 1, n, u, w); } else{ int v, l, r, w; v = read(), l = read(), r = read(), w = read(); S.Update_in(root_in, l, r, 1, n, v, w); } } Spfa(s); for(register int i = 1; i <= n; i++){ if(dis[i] == 4557430888798830399) printf("-1 "); else printf("%lld ", dis[i]); } return 0; }
P6348 [PA2011]Journeys
Code
点击查看代码
#include<queue> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int MAXN = 8e6 + 10; int n, m, p, cnt, tot, root_in, root_out; int head[MAXN], dis[MAXN]; bool used[MAXN]; struct Edge{ int to, next, dis; }e[MAXN]; inline void Add(int u, int v, int w){ e[++cnt].to = v; e[cnt].dis = w; e[cnt].next = head[u]; head[u] = cnt; } struct Segment_Tree{ struct Tree{ int lson, rson; }tr[MAXN << 2]; #define lson(x) tr[x].lson #define rson(x) tr[x].rson void Build_in(int &rt, int l, int r){ if(l == r){ rt = l; return; } rt = ++tot; int mid = (l + r) >> 1; Build_in(lson(rt), l, mid); Build_in(rson(rt), mid + 1, r); Add(rt, lson(rt), 0); Add(rt, rson(rt), 0); } void Build_out(int &rt, int l, int r){ if(l == r){ rt = l; return; } rt = ++tot; int mid = (l + r) >> 1; Build_out(lson(rt), l, mid); Build_out(rson(rt), mid + 1, r); Add(lson(rt), rt, 0); Add(rson(rt), rt, 0); } void Update_in(int rt, int l, int r, int L, int R, int u, int w){ if(l <= L && r >= R){ Add(u, rt, w); return; } int mid = (L + R) >> 1; if(l <= mid) Update_in(lson(rt), l, r, L, mid, u, w); if(r > mid) Update_in(rson(rt), l, r, mid + 1, R, u, w); } void Update_out(int rt, int l, int r, int L, int R, int v, int w){ if(l <= L && r >= R){ Add(rt, v, w); return; } int mid = (L + R) >> 1; if(l <= mid) Update_out(lson(rt), l, r, L, mid, v, w); if(r > mid) Update_out(rson(rt), l, r, mid + 1, R, v, w); } }S; struct Road{ int pos; long long dis; bool operator < (const Road &a) const { return dis > a.dis; } }; void Dijkstra(int x){ priority_queue<Road> q; memset(used, 0, sizeof(used)); memset(dis, 0x3f, sizeof(dis)); dis[x] = 0; q.push((Road){x, dis[x]}); while(!q.empty()){ int k = q.top().pos; q.pop(); if(used[k]) continue; used[k] = true; for(register int i = head[k]; i; i = e[i].next){ int v = e[i].to; if(dis[v] > dis[k] + e[i].dis){ dis[v] = dis[k] + e[i].dis; q.push((Road){v, dis[v]}); } } } } inline int read(){ int x = 0, f = 1; char c = getchar(); while(c < '0' || c > '9'){ if(c == '-') f = -1; c = getchar(); } while(c >= '0' && c <= '9'){ x = (x << 1) + (x << 3) + (c ^ 48); c = getchar(); } return x * f; } int main(){ n = read(), m = read(), p = read(); tot = n; S.Build_in(root_in, 1, n); S.Build_out(root_out, 1, n); for(register int i = 1; i <= m; i++){ int a, b, c, d; a = read(), b = read(), c = read(), d = read(); int p1 = ++tot; S.Update_out(root_out, a, b, 1, n, p1, 1); S.Update_in(root_in, c, d, 1, n, p1, 1); int p2 = ++tot; S.Update_out(root_out, c, d, 1, n, p2, 1); S.Update_in(root_in, a, b, 1, n, p2, 1); } Dijkstra(p); for(register int i = 1; i <= n; i++) printf("%d\n", dis[i] / 2); return 0; }
以下为博客签名,与博文无关。
只要你们不停下来,那前面就一定有我。所以啊,不要停下来~
本文来自博客园,作者:TSTYFST,转载请注明原文链接:https://www.cnblogs.com/TSTYFST/p/16586525.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理