1. 程式人生 > >樹的最小支配集、最小點覆蓋、最大獨立集【模板】

樹的最小支配集、最小點覆蓋、最大獨立集【模板】

最小支配集:指從所有頂點中取儘量少的點組成一個集合,使得剩下的所有點都與取出來的點有邊相連。頂點個數最小的支配集被稱為最小支配集。這裡用貪心法來求。

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集

多源短路徑FloydFloyd求模板

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