SDOI2018 戰略遊戲 圓方樹 鏈並

2021-10-02 04:50:32 字數 1470 閱讀 1870

題目描述:

n個點m條邊的無向連通圖,每次詢問給出s

ss個點,問有多少不在s

ss中的點使得在圖中刪去它後在s

ss中存在兩點u,v

u,vu,

v不連通。

2 ≤n

≤105

,n−1

≤m≤2

∗105

,2≤∣

s∣,∑

∣s∣≤

2∗10

52\le n\le10^5,n-1\le m\le2*10^5,2\le|s|,\sum|s|\le2*10^5

2≤n≤10

5,n−

1≤m≤

2∗10

5,2≤

∣s∣,

∑∣s∣

≤2∗1

05題目分析:

圓方樹上s個點之間的圓點個數即為所求。

求鏈並當然可以建一波虛樹

只需要將s個點按照dfs排序後,設dis[x]表示x到根的圓點個數,依次加入dis[a[i]]+dis[a[i+1]]-2*dis[lca(a[i],a[i+1])],相當於每次加入a[i]到a[i+1]的路徑(沒有算lca,相當於加入邊),每次加完後除了最外圍的一條鏈,其他的邊都被算了兩次。這樣只需要最後再加上dis[a[k]]+dis[a[1]]-2*dis[lca(a[k],a[1])],就將路徑上的每條邊都算了兩次,除以2後加上[lca(a[k],a[1])為圓點],最後減去|s|即可。

code:

#include

#define maxn 400005

using

namespace std;

int n,m,q,sz;

vector<

int>g[maxn]

,e[maxn]

;inline

void

lineg

(int x,

int y)

inline

void

linee

(int x,

int y)

namespace graph

}else low[u]

=min

(low[u]

,dfn[v]);

}}const

int log =18;

int dis[maxn]

,dep[maxn]

,dfn[maxn]

,tim,f[maxn]

[log+2]

,seq[maxn]

;void

dfs(

int u,

int ff)

intlca

(int u,

int v)

inline

bool

cmp(

int x,

int y)

intmain()

}}

SDOI2018 戰略遊戲 廣義圓方樹 虛樹

很容易發現一點,題目要我們求的實際上就是我們的新構的樹中的,圓點的個數,所以呢,在這裡我們可以直接通過先利用廣義圓方樹來再求乙個虛樹,我們直接查詢虛樹就可以完成這個要求了。include include include include include include include include ...

SDOI2018 戰略遊戲

給定一張 n 個點 m 條邊的無向聯通圖,共有 q 次操作,每次操作選擇一些點作為關鍵點,詢問有多少個點滿足刪去該點及與其相鄰的邊後,至少有兩個關鍵點不能互相到達。n,q leq 10 5,m leq 2 cdot 10 5,sum s leq 2 cdot 10 5 還是挺簡單的。就是圓方樹 虛樹...

SDOI2018 戰略遊戲

題目 圓方樹其實並沒有那麼難 圓方樹的構建比較簡單,就是乙個tarjan把點雙跑出來,對於每乙個點雙我們多建乙個方點,把原圖中的點稱為圓點,將點雙內所有圓點向方點連邊,之後我們就得到了原圖的圓方樹 關於圓方樹的性質,zyb大爺在他的題解裡寫了很多,這裡就不再抄一遍了 至於這道題,就是把圓點拿出來建棵...