樹的最小支配集、最小點覆蓋、最大獨立集【模板】
最小支配集:指從所有頂點中取儘量少的點組成一個集合,使得剩下的所有點都與取出來的點有邊相連。頂點個數最小的支配集被稱為最小支配集。這裡用貪心法來求。
1.以1號點深度優先搜尋整棵樹,求出每個點在DFS中的編號和每個點的父親節點編號。
2.按DFS的反向序列檢查,如果當前點既不屬於支配集也不與支配集中的點相連,且它的父親也不屬於支配集,將其父親點加入支配集,支配集個數加1。
3.標記當前結點、當前結點的父節點(屬於支配集)、當前結點的父節點的父節點(與支配集中的點相連)。
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
const int MAXN = 20020;
struct EdgeNode
{
int to;
int next;
}Edges[MAXN];
int Head[MAXN],father[MAXN],NewPos[MAXN];
bool vis[MAXN];
//NewPos[]表示深度優先遍歷序列的第i個點是哪個點
//now表示當前深度優先遍歷序列中已經有多少個點了
//vis[]用來深度優先遍歷的判重
//father[]表示點i的父親節點編號
int N,M,now;
void DFS(int x) //得到深度優先佇列的反向序列
{
NewPos[now++] = x;
for(int k = Head[x]; k != -1; k = Edges[k].next)
{
if(!vis[Edges[k].to])
{
vis[Edges[k].to] = true;
father[Edges[k].to] = x;
DFS(Edges[k].to);
}
}
}
//S[i]為true,表示第i個點被覆蓋了
//Set[i]表示點i屬於要求的點集
bool S[MAXN],Set[MAXN];
int Greedy()//貪心求最小支配集
{
memset(S,0,sizeof(S));
memset(Set,0,sizeof(Set));
int ans = 0;
for(int i = N-1; i >= 1; i--)//反向序列檢查
{
int t = NewPos[i];
if(!S[t])//當前點未被覆蓋,也就是當前點既不屬於支配集,也不與支配集中的點相連
{
if(!Set[father[t]])//當前點的父親結點不屬於支配集,
{
Set[father[t]] = true; //將父節點加入支配集
ans++; //頂點個數加1
}
S[t] = true;
S[father[t]] = true;
S[father[father[t]]] = true;
//標記當前點、當前結點的父節點、當前結點的父節點的父節點
}
}
return ans;
}
int main()
{
int u,v;
while(~scanf("%d",&N))
{ //初始化
memset(Edges,0,sizeof(Edges));
memset(Head,-1,sizeof(Head));
memset(father,0,sizeof(father));
memset(vis,false,sizeof(vis));
memset(NewPos,0,sizeof(NewPos));
int id = 0;
for(int i = 0; i < N-1; ++i)
{
scanf("%d%d",&u,&v);
Edges[id].to = v;
Edges[id].next = Head[u];
Head[u] = id++;
Edges[id].to = u;
Edges[id].next = Head[v];
Head[v] = id++;
}
now = 0;
vis[1] = true;
father[1] = 1;
DFS(1);
printf("%d\n",Greedy());
}
return 0;
}
最小點覆蓋:指從所有頂點中取儘量少的點組成一個集合,使得集合中所有的邊都與取出來的點有邊相連。頂點個數最小的覆蓋集被稱為最小點覆蓋。
貪心策略:如果當前點和當前點的父節點都不屬於頂點覆蓋集合,則將父節點加入到頂點覆蓋集合中,並標記當前節點和其父節點都被覆蓋。
int Greedy()//貪心求最小點覆蓋
{
memset(S,0,sizeof(S));
memset(Set,0,sizeof(Set));
int ans = 0;
for(int i = N-1; i >= 1; i--)//反向序列檢查
{
int t = NewPos[i];
if(!S[t] && !S[father[t]])//當前點和當前點的父節點都不屬於頂點覆蓋集合
{
Set[father[t]] = true; //當前點的父節點加入到頂點覆蓋集合中
ans++; //頂點個數+1
S[t] = true;
S[father[t]] = true;
//標記當前點、當前結點的父節點
}
}
return ans;
}
最大獨立集:指從所有頂點中取儘量多的點組成一個集合,使得這些點之間沒有邊相連。頂點個數最多的獨立集被稱為最大獨立集。
貪心策略:如果當前節點沒有被覆蓋,則將當前節點加入獨立集,並標記當前節點和其父節點都被覆蓋。
int Greedy()//貪心求最大獨立集
{
memset(S,0,sizeof(S));
memset(Set,0,sizeof(Set));
int ans = 0;
for(int i = N-1; i >= 1; i--)//反向序列檢查
{
int t = NewPos[i];
if(!S[t])//當前點未被覆蓋
{
Set[t] = true; //將當前點加入獨立集
ans++; //獨立集點個數加1
S[t] = true;
S[father[t]] = true;
//標記當前點、當前結點的父節點都被覆蓋
}
}
return ans;
}
相關推薦
hdu——3367 並查集+最大生成樹【模板】
In graph theory, a pseudoforest is an undirected graph in which every connected component has at most one cycle. The maximal pseudofores
樹的最小支配集、最小點覆蓋、最大獨立集 (貪心orDP)
樹的最小支配集:點集中取出儘量少的點,使剩下的點與取出來的點都有邊相連。 樹的最小點覆蓋:點集中取出儘量少的點,使得所有邊都與選出的點相連。 樹的最大獨立集:點集中取出儘量多的點,使得這些點兩兩之間沒有
樹的最小支配集、最小點覆蓋、最大獨立集【模板】
最小支配集:指從所有頂點中取儘量少的點組成一個集合,使得剩下的所有點都與取出來的點有邊相連。頂點個數最小的支配集被稱為最小支配集。這裡用貪心法來求。 1.以1號點深度優先搜尋整棵樹,求出每個點在DFS中的編號和每個點的父親節點編號。 2.按DFS的反向序列檢
求樹的最大獨立集,最小點覆蓋,最小支配集 貪心and樹形dp
www 子節點 最大獨立集 com 倒序 最小支配集 交流 屬於 else 目錄 求樹的最大獨立集,最小點覆蓋,最小支配集 三個定義 貪心解法 樹形DP解法 (有任何問題歡迎留言或私聊&&歡迎交流討論哦 求樹的最大獨立集,最小點覆蓋,最小支配集 三個
樹的最小支配集,最小點覆蓋與最大獨立集
首先看一下三者的定義: 定義1 對於圖G=(V,E)來說, 最小支配集 指的是從V中取儘量少的點組成一個集合,使得對於V中剩餘的點都與取出來的點有邊相連。也就是說,設V‘是圖G的一個支配集,則對於
樹的最小支配集, 最小點覆蓋, 最大獨立集, 重心, 直徑, 以及樹上最大匹配
學習連線 先講定義: 最小支配集 對於圖G = (V, E) 來說,最小支配集指的是從 V 中取儘量少的點組成一個集合, 使得 V 中剩餘的點都與取出來的點有邊相連.也就是說,設 V’
二分圖中對最小頂點覆蓋、最小邊覆蓋、最大獨立集的理解[轉]
一次 一個 cnblogs 相交 style 個人理解 base 邊集 依然 原貼鏈接:http://blog.csdn.net/flynn_curry/article/details/52966283 僅僅用於自己理解,若有共鳴,別太吐槽就行哈~ 首先是匈牙利算
最大匹配、最小頂點覆蓋、最大獨立集、最小路徑覆蓋(轉)
在講述這兩個演算法之前,首先有幾個概念需要明白: 二分圖: 二分圖又稱二部圖,是圖論中的一種特殊模型。設G=(V,E)是一個無向圖,如果頂點V可以分割為兩個互不相交的子集(A,B),並且圖中的每條邊(i,j)所關聯的兩個頂點i和j分別屬於這兩個不同的頂點集(i in A, j in
最小支配集,最小點覆蓋,最大獨立集(貪心/DP)
最小支配集(minimal dominating set):對於圖G=(V,E)來說,設V'是圖G的一個支配集,則對於圖中的任意一個頂點u,要麼屬於集合V',要麼與V'中的頂點相連。 在V'中除去任何元素後V'不再是支配集,則支配集V'是極小支配集。稱G中所有支配集中頂點個
【LA3415 訓練指南】保守的老師 【二分圖最大獨立集,最小割】
style ide using algorithm lar 音樂 \n ios 學生 題意 Frank是一個思想有些保守的高中老師。有一次,他需要帶一些學生出去旅行,但又怕其中一些學生在旅行中萌生愛意。為了降低這種事情發生的概率,他決定確保帶出去的任意兩個學生至少要滿
二分圖的最小頂點覆蓋 最大獨立集 最大團
所有 mil bubuko 開始 畫的 很好 info 最大團 集合 二分圖的最小頂點覆蓋 定義:假如選了一個點就相當於覆蓋了以它為端點的所有邊。最小頂點覆蓋就是選擇最少的點來覆蓋所有的邊。 方法:最小頂點覆蓋等於二分圖的最大匹配。 我們用二分圖來構造最小頂點覆蓋。 對於
hihocoder1127 二分圖三·二分圖最小點覆蓋和最大獨立集
use cto nbsp 二分圖 std ans true ace spa 思路: 對於不存在孤立點的圖,|最大匹配| + |最小邊覆蓋| = |V|,|最大獨立集| + |最小頂點覆蓋| = |V|。對於二分圖而言,|最大匹配| = |最小頂點覆蓋|。(V是圖的頂點集合)
最大匹配 最小點覆蓋 最小邊覆蓋 最大獨立集
最大匹配: 匹配:在圖論中,一個「匹配」(matching)是一個邊的集合,其中任意兩條邊都沒有公共頂點。 最大匹配:一個圖所有匹配中,所含匹配邊數最多的匹配,稱為這個圖的最大匹配。 最小點覆蓋: 點覆蓋的概念定義: 對於圖G=(V,E)中的一個點覆蓋是
【模板】最小割樹(Gomory-Hu Tree)-bzoj2229&4519
模板傳送門:洛谷【模板】最小割樹 相關的題目都很板。。。 題意 給定一個 n n n個點
【每日演算法】【圖論】【最小邊覆蓋 & 最小路徑覆蓋 & 最小頂點覆蓋 & 最大獨立集 & 最大團】
最小邊覆蓋 = 最大獨立集 = |V| - 最大匹配數 這個是在原圖是二分圖上進行的 最小路徑覆蓋和最小邊覆蓋不同,不要求給的圖是二分圖,而是要求是N x N的有向圖,不能有環,然後根據原圖構造二分圖,構造方法是將點一分為二,如,i分為i1和i2然後如果i和j有邊,那麼就在i
最小點覆蓋,最小邊覆蓋,最大匹配,最小路徑覆蓋,最大獨立集總結。
如果沒有申明是什麼圖預設是二分圖 最小點覆蓋: 點覆蓋的概念定義: 對於圖G=(V,E)中的一個點覆蓋是一個集合S⊆V使得每一條邊至少有一個端點在S中。 最小點覆蓋:就是中點的個數最少的S集
多源最短路徑Floyd、Floyd求最小環【模板】
Floyd演算法:用來找出每對點之間的最短距離。圖可以是無向圖,也可以是有向圖,邊權可為正,也可以為負,唯一要求是不能有負環。 1.初始化:將Map[][]中的資料複製到Dist[][]中作為每對頂點
二分圖相關定理及其證明(最小點覆蓋+最小路徑覆蓋+最大獨立集+最小覆蓋集)
①最小路徑覆蓋: 給定有向圖G=(V,E)。設P 是G 的一個簡單路(頂點不相交)的集合。如果V 中每個頂點恰好在P 的一條路上,則稱P是G 的一個路徑覆蓋。P 中路徑可以從V 的任何一個頂點開始,長度也是任意的,特別地,可以為0。G 的最小路徑覆蓋是G 的所含路徑條數最少的路徑覆蓋。 路徑覆蓋
【最小割/二分圖最大獨立集】【網絡流24題】【P2774】 方格取數問題
getc 如果 size etc lse fine std set solution Description 給定一個 \(n~\times~m\) 的矩陣,每個位置有一個正整數,選擇一些互不相鄰的數,最大化權值和 Limitation \(1~\leq~n,~m~\leq
[洛谷3381]【模板】最小費用最大流
main 最小費用最大流 spf 最大流模板題 rem digi span mem spfa 思路:最小費用最大流模板題。用EdmondsKarp,增廣時使用SPFA求最短路。 1 #include<queue> 2 #include<cstd