生活随笔
收集整理的這篇文章主要介紹了
Legacy(线段树优化建边跑Dijkstra)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
Legacy
線段樹優化建邊,開兩顆線段樹:
對于線段樹1,自頂向下連邊。對于線段樹2,自底向上連邊。
然后對于op1我們直接連邊即可。
對于op2(u -> [l, r] cost = w),這個操作在線段樹1上完成即可。
對于op3([l, r] -> v cost = w),這個操作在線段樹2上完成即可。
最后跑一遍Dijkstra最短路即可。
#include <bits/stdc++.h>
#define mid (l + r >> 1)
#define lson rt << 1, l, mid
#define rson rt << 1 | 1, mid + 1, r
#define ls rt << 1
#define rs rt << 1 | 1using namespace std
;typedef long long ll
;const int N
= 2e6 + 10;int n
, m
, s
, tree1
[N
], tree2
[N
], tot
;int head
[N
], to
[N
], nex
[N
], value
[N
], vis
[N
], cnt
= 1;ll dis
[N
];void add(int x
, int y
, int w
) {to
[cnt
] = y
;nex
[cnt
] = head
[x
];value
[cnt
] = w
;head
[x
] = cnt
++;
}int build1(int rt
, int l
, int r
) {if(l
== r
) {return tree1
[rt
] = l
;}tree1
[rt
] = ++tot
;int lid
= build1(lson
);int rid
= build1(rson
);add(tree1
[rt
], lid
, 0);add(tree1
[rt
], rid
, 0);return tree1
[rt
];
}int build2(int rt
, int l
, int r
) {if(l
== r
) {return tree2
[rt
] = l
;}tree2
[rt
] = ++tot
;int lid
= build2(lson
);int rid
= build2(rson
);add(lid
, tree2
[rt
], 0);add(rid
, tree2
[rt
], 0);return tree2
[rt
];
}void add1(int rt
, int l
, int r
, int u
, int L
, int R
, int w
) {if(l
>= L
&& r
<= R
) {add(u
, tree1
[rt
], w
);return ;}if(L
<= mid
) add1(lson
, u
, L
, R
, w
);if(R
> mid
) add1(rson
, u
, L
, R
, w
);
}void add2(int rt
, int l
, int r
, int v
, int L
, int R
, int w
) {if(l
>= L
&& r
<= R
) {add(tree2
[rt
], v
, w
);return ;}if(L
<= mid
) add2(lson
, v
, L
, R
, w
);if(R
> mid
) add2(rson
, v
, L
, R
, w
);
}typedef pair
<ll
, int> pli
;priority_queue
<pli
, vector
<pli
>, greater
<pli
> > q
;void Dijkstra() {memset(dis
, 0x3f, sizeof dis
);dis
[s
] = 0;q
.push(make_pair(0, s
));while(q
.size()) {int temp
= q
.top().second
;q
.pop();if(vis
[temp
]) continue;vis
[temp
] = 1;for(int i
= head
[temp
]; i
; i
= nex
[i
]) {if(dis
[to
[i
]] > dis
[temp
] + value
[i
]) {dis
[to
[i
]] = dis
[temp
] + value
[i
];q
.push(make_pair(dis
[to
[i
]], to
[i
]));} }}for(int i
= 1; i
<= n
; i
++) {printf("%lld%c", dis
[i
] == 0x3f3f3f3f3f3f3f3f ? -1 : dis
[i
], i
== n
? '\n' : ' ');}
}int main() {scanf("%d %d %d", &n
, &m
, &s
);tot
= n
;build1(1, 1, n
);build2(1, 1, n
);for(int i
= 1; i
<= m
; i
++) {int op
, x
, y
, l
, r
, w
;scanf("%d", &op
);if(op
== 1) {scanf("%d %d %d", &x
, &y
, &w
);add(x
, y
, w
);}else if(op
== 2) {scanf("%d %d %d %d", &x
, &l
, &r
, &w
);add1(1, 1, n
, x
, l
, r
, w
);}else {scanf("%d %d %d %d", &x
, &l
, &r
, &w
);add2(1, 1, n
, x
, l
, r
, w
);}}Dijkstra();return 0;
}
總結
以上是生活随笔為你收集整理的Legacy(线段树优化建边跑Dijkstra)的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。