洛谷P4319 變化的道路

2022-04-30 10:57:07 字數 3152 閱讀 4479

題意:給定圖,每條邊都有一段存在時間。求每段時間的最小生成樹。

解:動態mst什麼毒瘤...洛谷上還是藍題...

線段樹分治 + lct維護最小生成樹。

對時間開線段樹,每條邊的存在時間在上面會對應到logn個區間。

我們先把這些邊加到線段樹對應節點上,但是不在lct上面加。最後掃一遍線段樹。

掃到乙個節點的時候把當前節點上的邊加入lct,同時記錄做了什麼操作。回溯的時候還原操作。

最小生成樹的權值不用lct維護子樹和,直接用乙個變數,加邊刪邊的時候跟著修改即可。

這樣複雜度就是nlog2n的...雖然常數上天了。

注意一下就是,回溯操作的時候順序必須嚴格倒序。否則會出現一些情況導致re。

1 #include 2 #include 3 #include 4

5 typedef long

long

ll;6

const

int n = 500010, lm = 32766;7

8int fa[n], s[n][2

], large[n], p[n], top;

9bool

rev[n];

10ll val[n];

1112 inline void pushup(int

x) 17

if(s[x][1] && val[large[x]] < val[large[s[x][1

]]])

20return;21

}2223 inline void pushdown(int

x) 29

if(s[x][1

]) 32 rev[x] = 0;33

}34return;35

}3637 inline bool no_root(int

x) 40

41 inline void rotate(int

x) 50 s[y][f] = s[x][!f];

51if(s[x][!f])

54 s[x][!f] =y;

55 fa[y] =x;

5657

pushup(y);

58return;59

}6061 inline void splay(int

x) 68

while

(top)

7273 y =fa[x];

74int z =fa[y];

75while

(no_root(x))

80rotate(x);

81 y =fa[x];

82 z =fa[y];83}

84pushup(x);

85return;86

}8788 inline void access(int

x) 98

return;99

}100

101 inline void make_root(int

x) 107

108 inline int find_root(int

x) 115

return

x;116

}117

118 inline void link(int x, int

y) 124

125 inline void cut(int x, int

y) 134

135 inline int getmax(int x, int

y) 141

//lct over

142143

struct

edge

151}edge[n];

152153

struct

node

160};

161162 std::vectorid[n];

163 std::vectorv[n];

164int

n;165

ll sum;

166167

void add(int l, int r, int v, int l, int r, int

o) 172

int mid = (l + r) >> 1

;173

if(l <=mid)

176if(mid

179return

;180

}181

182void solve(int l, int r, int

o) 191

cut(edge[p].u, p);

192cut(edge[p].v, p);

193link(x, t);

194link(y, t);

195 v[o].push_back(node(1

, p));

196 v[o].push_back(node(0, t)); //

pay attention! this must be behind

197 sum -=val[p];

198 sum +=val[t];

199//

printf(" > push %d %d \n", t, p);

200}

201if(l ==r)

204else

209//

printf(" -- solve %d %d %d \n", l, r, o);

210for(int i = v[o].size() - 1; i >= 0; i--)

217else

222//

printf(" -- > pop %d \n", t);

223}

224v[o].clear();

225return

;226

}227

228int

main()

242int

m;243 scanf("

%d", &m);

244for(int i = 1, l, r; i <= m; i++)

250251 solve(1, lm, 1

);252

253return0;

254 }

ac**

洛谷P2296 尋找道路

在有向圖g 中,每條邊的長度均為1 現給定起點和終點,請你在圖中找一條從起點到終點的路徑,該路徑滿足以下條件 1 路徑上的所有點的出邊所指向的點都直接或間接與終點連通。2 在滿足條件1 的情況下使路徑最短。注意 圖g 中可能存在重邊和自環,題目保證終點沒有出邊。請你輸出符合條件的路徑的長度。輸入格式...

洛谷 P2296 尋找道路

題目描述 在有向圖g 中,每條邊的長度均為1 現給定起點和終點,請你在圖中找一條從起點到終點的路徑,該路徑滿足以下條件 1 路徑上的所有點的出邊所指向的點都直接或間接與終點連通。2 在滿足條件1 的情況下使路徑最短。注意 圖g 中可能存在重邊和自環,題目保證終點沒有出邊。請你輸出符合條件的路徑的長度...

洛谷 P2296 尋找道路

題目大意 在乙個有向圖中找出2點之間的最短路,並且路徑上的所有點的出邊所指向的點都直接或間接與終點連通。題解 spfa 佇列 dfs 1.從終點方向搜,把終點能到的點標記可到達。2.把終點能到達的點的出邊判斷,如果出邊未被標記則狀態更新為不可到達。3.做spfa,若t i 可以到達就做,不然不做。v...