POJ- теория графов - непересекающиеся-набор шаблоны
. 1, INIT : каждый элемент инициализируется с набором инициализации каждого родительским узла является его собственный элементом, каждый элемент узла - предка сам (и может изменяться в зависимости от ситуации).
аннулированию в инициализации () { для ( INT I = 1. ; я <= п; я ++) P [I] = я; // Р [I] является родительским узлом номера узла я }
2, Находка (Х-) : Найти набор элементов , расположенных, то есть где предки найти коллекцию этого элемента , чтобы определить , является ли две принадлежат одному и тому же набору элементов, просто посмотрите , где они же набор предков может быть. Слияние двух наборов, но и коллекция предка стали предками другого набора.
INT Найти ( INT X) { возвращение Х == Р [Х] Х :? Р [Х] = Найти (Р [Х]); // вкл путь компрессора }
. 3, Союза (х, у) : Комбинированный х, у , где эти два набора, с помощью функции поиска () , чтобы найти предка , в котором два комплекта, один набор предков предка другого заданного значения. фигура
аннулируется Союз ( INT х, ИНТ у) { х = Find (х) у = Find (у); IF (х == у) возвращение ; в остальном Р [у] = х; // объединенное дерева х у дерева на корень х }
POJ 2524 Вездесущие Религии
Проблема решения идеи
Disjoint набора название запись, сколько различных компонент связности можно получить там.
AC код
# include <cstdio> Const INT N = 50500 ; INT Р [N]; // родительская группа узлов Int н-, м; // количество узлов и отношения узла аннулированию к инициализации () { для ( INT I = 0 ; Я <п, я ++) Р [I] = I; // инициализирует сам родительский узел, который представляет собой изолированный одиночный узел дерева } INT находка ( INT х) // найти корень дерева , где х { возвращение (х Р == [х]) х :? Р [х] = Найти (Р [х]); } недействительным Союза ( Int х, INT у) // в сочетании, у й дерево слияния дерева { х = находка (х); у = находка (у); если (х == у) возвращение ; остальной р [у] = х; } INT основных () { INT CNT = 1 ; в то время как (зсапЕ ( " % d% d " , & п, & м)! = EOF) { если (п == 0 && м == 0 ) перерыв ; ИНТ х, у; в этом(); // 初始化,清空数组 для ( INT I = 0; г <т; я ++ ) { зсапЕ ( " % d% d " , & х, & у); Союз (х, у); } INT ANS = 0 ; для ( INT I = 0 ; <п; я ++ ) { если (я == р [я]) ANS ++ ; } Е ( " Случай% d:% d \ п " , CNT ++ , ANS); } Возвращает 0 ; }
POJ 1611 Подозреваемых
Проблема решения идеи
В команде более чем один человек, второй человек в результате слияния, где человек подобен первой группе.
AC код
# include <cstdio> Const INT N = 30300 ; INT Р [N]; // родительская группа узлов Int н-, м; // количество узлов и отношения узла аннулированию к инициализации () { для ( INT I = 0 ; Я <п, я ++) Р [I] = I; // инициализирует сам родительский узел, который представляет собой изолированный одиночный узел дерева } INT находка ( INT х) // найти корень дерева , где х { возвращение (х Р == [х]) х :? Р [х] = Найти (Р [х]); } недействительным Союза ( Int х, INT у) // в сочетании, у й дерево слияния дерева { х = находка (х); у = находка (у); если (х == у) возвращение ; остальной р [у] = х; } INT основных () { в то время как (зсапЕ ( " % d% D " , & п, & м) =! EOF) { если (п == 0 && м == 0 ) перерыва ; ИНТ groupNum, х, у; в этом(); // 初始化,清空数组 в то время (m-- ) { зсапЕ ( " % d% d ", & GroupNum, & Х); это время (- GroupNum) { Scanf ( " % D " , & Y); Юнион (X, Y); // каждого члена в сочетании с первой группой , где один компонент } } Int = ANS 0 ; для ( INT I = 0 ; I <п, I ++) // сам пациенты { IF (Найти (I) Найти == ( 0 )) ANS ++; // и студент отношения 0 } Е ( " % D \ n- ", Года); } Возврат 0 ; }