以下所有圖,點數n是1e5,邊數是1e6
題意:找到乙個生成樹,使得度數最大的點度數最大
sol:
直接找原圖中度數最大的點p,把p的所有邊都加入生成樹,再kruskal即可
題意:找到乙個生成樹,使得1號點度數恰好為k
sol:
法一:把一號點刪掉,看圖被分成了多少個連通塊(dfs即可),每個連通塊塗成一種顏色
把一號點和每個連通塊至少連乙個邊。和k比較決定即可。
或者求割點,如果一號點是割點,也可以求出周圍的塊(麻煩,注意割點不完全屬於任何點雙)
法二:下面寫。
題意:找到乙個生成樹,使得每個點度數小於n/2
sol:
前面的方法不行了。
法一:(?)
求割點,考慮每個割點pi對周圍的每個點雙至少要連線一條邊。
但是在pi的出邊連線的點也是割點pj的時候,無法判斷pj「屬於」哪個點雙。。(反正不會優化。。。。只能n^2)
法二:反正來。玩修正主義
先隨便找乙個生成樹。
如果有乙個點度數》n/2(這樣的點最多乙個,反證即可),這個點就當作根root。
考慮其他沒有加入的邊,如果和root構成環,那麼就砍掉root和某個兒子的邊,並加入新邊。
注意,加入新邊不能使得有新的點度數》n/2,加入的時候判斷即可。
這樣是對的。
因為最後正確答案如果存在,那麼會有多個。
在有答案的情況下,(即每個割點連線的點雙不多於n/2個)
隨機生成樹度數大於n/2的點root,
如果是原圖的割點,那麼可以調整
如果不是原圖的割點,那麼也可以調整。
實現方法:(比較巧妙)
(首先可以lct暴力維護lca)
然後其實可以把root的每個兒子子樹看成一塊,用並查集,開始的時候每個塊的點,分別指向對應的root的兒子。
然後加入邊的時候,涉及si,sj兩個兒子,
兒子si和root的邊斷了,就讓si並查集中的father為sj,對應連通塊的合併。
(因為si和root的邊不會再連上,所以這樣就是對的。)
**:
#includeusingnamespace
std;
const
int m=5e5+9
;int
n,m,num,root;
intf[m],u[m],v[m],du[m];
int head[m],in
[m];
bool
vis[m];
struct pe[m<<2
];void dfs(int u,int fa,int
top)
}int find(int
x)void
work();head[x]=num;
e[++num]=p;head[y]=num;
du[x]++;du[y]++;
vis[i]=1
; }
for(int i=1;i<=n;++i)
if(du[i]>n/2)root=i;
}for(int i=1;i<=n;++i)f[i]=i;
for(int i=head[root];i;i=e[i].ne)
for(int i=1;i<=m;++i)
vis[
in[fx]]=0
; vis[i]=1
; f[fx]=fy;
continue
; }
vis[
in[fy]]=0
; vis[i]=1
; f[fy]=fx;
}if(du[root]<=n/2
) }
else printf("
no\n");
}int
main()
同理,codeforces 1133f2的做法,也可以是把1號點的所有出邊都連上,如果度數大於n/2,那麼再調整即可。
(比icpc南京 好寫多了,不用考慮別的點是否度數會大於n/2)
啟用生成樹命令(spanning tree)
1 啟用生成樹 spanning tree vlan vlan list vlan號 2 配置交換機為根網橋 spanning tree vlan vlan list root primary 指定根網橋 secondary 備用根網橋 3 修改交換機的優先順序 spanning tree vlan...
度數換算 美瞳怎麼選度數?
美瞳怎麼選度數?由於鏡片與眼睛接觸距離的不同,美瞳 眼鏡與框架眼鏡的度數是有差別的,並且,這種差別會隨著近視度數的增高而越來越明顯,那麼作為近視一族我們應該如何選擇美瞳度數呢?框架眼鏡架在鼻樑上,與眼球間有一段距離,而美瞳 眼鏡則是直接戴于角膜之上,與眼球零距離接觸,因此,美瞳度數一般會比框架度數要...
高度陣列與最長公共字首
摘要 本文是關於字尾陣列的乙個拓展,問題模型來自於最長公共字首 longest common prefix array 問題,我們為解決該模型,在字尾陣列的基礎上設計了乙個精巧的陣列 高度陣列,同時由於該陣列在處理各類字串相關問題時有著較好的用途,因此值得掌握。本文將直接從高度陣列講起,假設讀者具有...