【学习笔记】线段树优化建图

先开坑,有时间再说。

例题

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;
}
posted @   TSTYFST  阅读(32)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
点击右上角即可分享
微信分享提示