byteotia城市有n個 towns m條雙向roads. 每條 road 連線 兩個不同的 towns ,沒有重複的road. 所有towns連通。
input
輸入n<=100000 m<=500000及m條邊
output
輸出n個數,代表如果把第i個點去掉,將有多少對點不能互通。
sample input
5 51 2
2 31 3
3 44 5
sample output88
1614
8hint
思路:根據割點的定義,若節點i
ii不是割點,那麼把節點i
ii關聯的邊都去掉之後,只有i
ii與其他n−1
n-1n−
1個點不連通,因此答案為2∗(
n−1)
2*(n-1)
2∗(n−1
);若節點i
ii為割點,那麼去掉與節點i
ii關聯的邊後,會把圖分成幾個連通塊,我們應該分別求得這些連通塊的大小,再計算答案。不妨設節點i
ii的子節點集合中,有t
tt個點s1,
s2……
sts_,s_……s_
s1,s2
……s
t滿足割點判定法則dfn
[i]<=l
ow[s
k]dfn[i]<=low[s_]
dfn[i]
<=l
ow[s
k],那麼刪除與節點i
ii關聯的邊後,無向圖至多分成t+2
t+2t+
2個連通塊:(1)節點i
ii自身單獨成乙個連通塊。(2)有t
tt個連通塊,分別由搜尋樹上以sks_
sk為根的子樹中的節點構成。(3)還可能有乙個連通塊由剩下的點構成。如圖:
設s iz
[x]siz[x]
siz[x]
表示以x
xx為根的子樹的大小,那麼刪掉乙個割點i
ii的貢獻為:∑k=
1tsi
z[sk
]∗(n
−siz
[sk]
)+1∗
(n−1
)+(n
−1−s
um)∗
(1+s
um)\sum_^siz[s_]*(n-siz[s_])+1*(n-1)+(n-1-sum)*(1+sum)
k=1∑t
siz[
sk]
∗(n−
siz[
sk]
)+1∗
(n−1
)+(n
−1−s
um)∗
(1+s
um)其中s
um=∑
k=1t
siz[
sk]其中sum=\sum_^siz[s_]
其中sum=
k=1∑
tsi
z[sk
]這些都是可以在tar
jantarjan
tarjan
的d fs
dfsdf
s過程中維護的。
#include
#include
using
namespace std;
typedef
long
long ll;
const
int maxn=
1e5+5;
const
int maxm=
5e5+5;
struct edge
edge[maxm<<1]
;bool cut[maxn]
;int head[maxn]
,dfn[maxn]
,low[maxn]
,siz[maxn]
;ll ans[maxn]
;int n,m,tot,num,root;
inline
void
addedge
(int x,
int y)
void
tarjan
(int x)
}else
low[x]
=min
(low[x]
,dfn[y]);
}if(cut[x]
) ans[x]
+=n-1+
ll(n-
1-sum)*(
1+sum)
;else
ans[x]=2
*(n-1)
;}intmain()
root=1;
tarjan(1
);for(
int i=
1;i<=n;i++
)printf
("%lld\n"
,ans[i]);
return0;
}
bzoj 1123 tarjan 乘法原理
題意 n個點,m條雙向邊,問刪除每個點後,對於有序數對 x,y 滿足x,y互不連通的數對數 即 1,2 與 2,1 算2對 其中,被刪掉的點也應被統計。題意明白以後,一眼看過去就是tarjan 因為要求統計被刪除的點,所以每個點的基礎答案為 n 1 2 如果刪去的點不是割點,則它除了基礎答案外不會再...
bzoj1123(許可權題)
割點的題目,一定要考慮全面。注意有序點對,必須 2。因為刪掉割點的所有邊後,可能形成的連通塊有 1 孤單的節點i自己 2 i的兒子的子樹們 3 除了這些點,剩下的所有點構成乙個 許可權題 include define n 100010 define m 500010 include using na...
Tarjan演算法求LCA
題源 這個題還是debug了好久。1.呼叫函式中如果要更改外部資料需要傳遞引用,其實傳遞引用往往效率更高,以後要多加注意這一點。2.忘寫並查集了 捂臉逃 3.題目要求的是距離而不是lca,認真審題。貼 include include include define maxn 100005 define...