車站分級 (線段樹優化建邊 拓撲序最長路)

2021-08-09 07:02:49 字數 1319 閱讀 2584

10.11

思路:

基本方法就是等級高的車站向等級低的車站連邊,最後跑拓撲序的最長路就是ans。

線段樹優化建邊的拓撲排序(線段樹的神奇應用)。

先是建虛點優化,邊數優化為2*n,但是發現建邊的複雜度是nm,考慮線段樹優化。

注意到經停站把車站序列劃分成了多個區間,每個區間對應o(log)個線段樹上的節點,因此連邊時可以把邊數由o(nm)優化到o(m*log(n))。線段樹中的上下層節點先連好邊,區間整體連邊的時候直接把線段樹上零散的塊連在虛點上即可。具體細節可以參考**。

#include 

#include

#include

#define n 400010

using

namespace

std;

struct edgeed[n * 20];

queue

q;struct nodepool[n * 20], *tail = pool, *root;

int n, m, idc=0, tot=0, ans=0;

int head[n], a[n], mrk[n], re[n], dis[n], in[n];

void adde(int u, int v)

node *build(int lf, int rg)

int mid = (lf + rg) >> 1;

nd->ls = build(lf, mid);

nd->rs = build(mid+1, rg);

adde(nd->ls->id, nd->id);//虛點

adde(nd->rs->id, nd->id);

return nd;

}void modify(node *nd, int lf, int rg, int l, int r, int pos)

int mid = (lf + rg) >> 1;

if(l <= mid) modify(nd->ls, lf, mid, l, r, pos);

if(r > mid) modify(nd->rs, mid+1, rg, l, r, pos);

}void solve()

while( !q.empty() )}}

}int main()

for(int k=2; k<=t; k++)

}solve();

for(int i=1; i<=n; i++)

ans = max(ans, dis[i]);

printf("%d\n", ans);

return

0;}

線段樹優化建邊

完整 總結例題 車站分級 這道題乍一看就能想到等級低的向等級高的連邊,即兩停靠站之間的站點向兩車站連邊,最後跑一遍拓撲排序找出最大值即為答案。以題目樣例為例,假設火車經過站點如下,其中藍色代表停靠,紅色代表不停靠 也就是說,2的等級一定比1 3 5和6低,4的等級一定比1 3 5和6低,建邊如下 拓...

線段樹優化建邊

對於許多的圖論題,有些題可能會出現結點要與區間內的每個點都進行建邊,但是如果進行遍歷建邊,那麼複雜度可能會被卡到 o n 2 此時線段樹的騷操作就出來了。我們知道線段樹的每個結點就是乙個區間,那麼我們就可以把點與區間建邊轉換為點與線段樹上的結點進行連邊。以下是幾道線段樹優化建邊的題目幫助您理解這個思...

線段樹優化連邊

有的時候,對於乙個點,向一段區間內所有點連邊 邊數是 o n 2 的 複雜度 於是就有了線段樹優化連邊.線段樹優化連邊,利用到線段樹的思想.對於每個區間,新建乙個節點,向子區間遞迴連邊.這樣,當連向一段區間,就等於連向了所有其子節點 十分抽象.看幾道例題 題目鏈結 暴力做法很顯然 連完邊後跑 tar...