SHOI2008 堵塞的交通

2022-05-02 05:51:07 字數 1495 閱讀 1560

這裡提供幾種不用腦子的演算法(當然是離線的):

$\text$

記下每條邊的刪除時間,用$\text$維護最大生成樹,每次加進一條邊時,跟原來那條鏈上的做比較,刪除那條刪除時間最短的邊即可。

線段樹分治

這個演算法將每條邊的加入和刪除時間加入到線段樹中,所以在遍歷到葉子節點時,那個時刻存在的邊都已經在並查集上了,於是直接判斷即可。

並查集用按秩合併就可以了,撤銷時記得按棧序撤銷。

lct找$hyj$去

線段樹分治

我的寫法可能(比較好看)並沒有建線段樹......

#include#include#include#include#include#include#define rg register

#define clear(x, y) memset(x, y, sizeof(x))

inline int read()

const int maxn(200010);

struct edge ;

std::pairq[maxn], stk[maxn << 2];

std::vectore;

std::mapg[maxn];

int fa[maxn], top, q_num, n, id[2][maxn], cnt, size[maxn];

char s[10];

inline int find(int x)

inline void merge(int x, int y)

inline void undo()

inline void div(int l, int r, std::vectore)

if(l == r) printf("%c\n", find(q[l].first) == find(q[l].second) ? 'y' : 'n');

else div(l, mid, l), div(mid + 1, r, r);

while(top > tmp) undo();

}int main()

); g[id[r1][c1]][id[r2][c2]] = g[id[r2][c2]][id[r1][c1]] = e.size() - 1;

} else if(s[0] == 'c') e[g[id[r1][c1]][id[r2][c2]]].end = q_num;

else if(s[0] == 'a') q[++q_num] = std::make_pair(id[r1][c1], id[r2][c2]);

} for(std::vector::iterator it = e.begin(); it != e.end(); ++it)

if(it -> end == -1) it -> end = q_num;

for(rg int i = 1; i <= n + n; i++) fa[i] = i, size[i] = 1;

div(1, q_num, e);

return 0;

}

SHOI2008 堵塞的交通

有一篇超級棒的線段樹 大力分類討論的題解!戳我 可是我還是不會寫這個做法qwqwqwq 這裡提供線段樹分治的寫法。感覺比較不需要智商,就是跑的有點慢了。include include include include include include include include define max...

SHOI2008 堵塞的交通

有一天,由於某種穿越現象作用,你來到了傳說中的小人國。小人國的布局非常奇特,整個國家的交通系統可 以被看成是乙個2行c列的矩形網格,網格上的每個點代表乙個城市,相鄰的城市之間有一條道路,所以總共有2c個 城市和3c 2條道路。小人國的交通狀況非常槽糕。有的時候由於交通堵塞,兩座城市之間的道路會變得不...

SHOI2008 堵塞的交通

題目描述 有一天,由於某種穿越現象作用,你來到了傳說中的小人國。小人國的布局非常奇特,整個國家的交通系統可 以被看成是乙個2行c列的矩形網格,網格上的每個點代表乙個城市,相鄰的城市之間有一條道路,所以總共有2c個 城市和3c 2條道路。小人國的交通狀況非常槽糕。有的時候由於交通堵塞,兩座城市之間的道...