日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Legacy(线段树优化建边跑Dijkstra)

發布時間:2023/12/4 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Legacy(线段树优化建边跑Dijkstra) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Legacy

線段樹優化建邊,開兩顆線段樹:
對于線段樹1,自頂向下連邊。對于線段樹2,自底向上連邊。
然后對于op1我們直接連邊即可。
對于op2(u -> [l, r] cost = w),這個操作在線段樹1上完成即可。
對于op3([l, r] -> v cost = w),這個操作在線段樹2上完成即可。
最后跑一遍Dijkstra最短路即可。

/*Author : lifehappy */ #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() {// freopen("in.txt", "r", stdin);// freopen("out.txt", "w", stdout);// ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);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);//x -> [l, r] cost w.add1(1, 1, n, x, l, r, w);}else {scanf("%d %d %d %d", &x, &l, &r, &w);//[l, r] -> x cost w.add2(1, 1, n, x, l, r, w);}}Dijkstra();return 0; }

總結

以上是生活随笔為你收集整理的Legacy(线段树优化建边跑Dijkstra)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。