題目描述
給出一張無向連通圖,求加最少的邊使得圖上任兩個節點之間都至少有兩條路徑。
思路題目的意思就是加邊使原圖成為一張邊雙聯通圖。我們考慮對無向圖進行縮點,這裡的縮點實質上就是把圖中的邊雙聯通分量縮為乙個點。我們考慮對於一張圖,顯然不需要在雙聯通分量內加邊,我們只需要在雙連通分量之間加邊。接下來考慮縮點之後的圖,最後一定是一棵樹,若不是一棵樹必定會有環,有環就應該被縮點。接下來就是這棵樹上的葉子節點,可以知道如果要使這張圖成為邊雙聯通圖,肯定不能存在度為1的點,否則必定只有一條路徑。
不過對於葉子節點我們可以證明必定存在一種加邊方法使得其為邊雙聯通分量,並且這種方案是最少的,數目為(leaf+1)/2。我們先考慮特殊情況,即只有乙個葉子節點的情況,那麼顯然原圖已經是乙個邊雙聯通圖,無需再考慮加邊。否則再考慮有兩個葉子節點,那麼原圖即為一條鏈,顯然只要加一條邊。其他情況,對於每個度為1的葉子節點,我們連一條邊每次選兩個葉子節點,這兩個葉子節點的路徑上至少有兩條連出去的邊,可以證明,只有葉子節點數大於3,肯定能找到這樣兩個點,而葉子結點數為3需要連兩條邊,所以按照這種方案我們肯定能取到這個加邊,並且將一條邊的發揮到極致,因此這是最優方案。
需要注意的是統計邊數時不要重複計邊,如果用前向星存圖要判重,不過也可以另開陣列存。
**
#include usingnamespace
std;
const
int n=5500,m=20020
;struct
edge
e[m];
intnxt[m],to[m],head[n],tot;
void add_edge(int x,int
y)int
read()
while(ch>='
0'&&ch<='9')
return res*w;
}int
dfn[n],low[n],st[n],vst[m],top,col,idx,co[n];
void tarjan(int
u)
else low[u]=min(low[u],dfn[v]);
}else vst[i]=1
;
if (dfn[u]==low[u])
--top;
}}int
deg[n];
intmain()
for(int i=1;i<=n;i++)
if(!dfn[i])tarjan(i);
for(int i=1;i<=r*2;i++)
}int cnt=0
;
for(int i=1;i<=col;i++)
if(deg[i]==1)cnt++;
printf("%d
",(cnt+1)/2
);}
AcWing 395 分離的路徑
要求兩個點之間至少要有兩條不相交的道路可以到達 那就是說兩個點在乙個環內 對於已經在環內的點就不用管了,所以先縮點 再對於縮完點之後的樹,入度為1 11的點之間是需要有一條邊的 所以每兩個葉子節點之間連一條邊,多出來的最後乙個點只能和別的環內的點連邊 所以最後的答案就是 le af 1 2 leaf...
分離目錄路徑和檔名
5 2 分離目錄路徑和檔名 輸入檔案目錄路徑和檔名,要求分離成目錄路徑和檔名分別輸出 輸入格式 例如 輸入 c windows winhelp.exe 輸出格式 c windows 目錄路徑 winhelp.exe 檔名 輸入樣例 usr bin man 輸出樣例 usr bin man inclu...
執行緒的分離與非分離狀態
執行緒的分離狀態決定乙個執行緒以什麼樣的方式來終止自己 非分離 joinable 分離 detached 非分離的執行緒能夠被其他執行緒收回其資源和殺死 在被其他執行緒 之前,它的儲存器資源 如棧 是不釋放的 預設狀態 分離的執行緒是不能被其他執行緒 或殺死的,它的儲存器資源在它終止時由系統自動釋放...