題意:給定圖,每條邊都有一段存在時間。求每段時間的最小生成樹。
解:動態mst什麼毒瘤...洛谷上還是藍題...
線段樹分治 + lct維護最小生成樹。
對時間開線段樹,每條邊的存在時間在上面會對應到logn個區間。
我們先把這些邊加到線段樹對應節點上,但是不在lct上面加。最後掃一遍線段樹。
掃到乙個節點的時候把當前節點上的邊加入lct,同時記錄做了什麼操作。回溯的時候還原操作。
最小生成樹的權值不用lct維護子樹和,直接用乙個變數,加邊刪邊的時候跟著修改即可。
這樣複雜度就是nlog2n的...雖然常數上天了。
注意一下就是,回溯操作的時候順序必須嚴格倒序。否則會出現一些情況導致re。
1 #include 2 #include 3 #include 4ac**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 }
洛谷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...