タイトル説明
特定の領域のn(n≤1000)犯罪組織、nは、1から番号がハイからローに彼らに危険の程度に応じて地元の警察は、暴力団との間に直接のリンクがあり,,そのうちのいくつかは、任意の2個の基であることができます接触直接的または間接的に、巨大な犯罪が形成されているので、ここでは、リスク犯罪グループの程度を一意にグループ内の犯罪組織の数によって決定されるではなく、単一の犯罪組織のリスクの度合いにかかわらず、危険度(の犯罪グループnまで)。地元警察は現在、大規模な犯罪者グループは、いくつかの小さなグループに分け、リスクの程度は、彼らがn / 2の最大値に過ぎないように、(すなわち、ギャングのできるだけを吹き飛ばす)として少しの時間を過ごしたいです。最良の結果を得るために、彼らは1 kに、k個のプログラムの最小値を取得してください番号が犯罪組織に対抗するための外となります。
入力形式
最初の行、正の整数n。
次のn行、各ラインは、正の整数の数、整数が存在する最初の行を除いて、第1の整数値を有し、正の整数k、i番目の行が存在する場合、Iを表し、2つのグループが直接Kであってもよいです連絡先。
出力フォーマット
正の整数、kの最小値。
サンプル入力
7
2 2 5
3 1〜3 4
2 2 4
2 2 3
3 1 6 7
2 5 7
2 5 6
サンプル出力
1
サンプル説明
出力1(犯罪組織との戦い)
問題の解決策
私たちは、$ N $の$ 1 $から列挙、列挙を逆にすることができます。
我々は$ I $を列挙するとき、我々は、iがj個の$側$(i、j)は$を<$組み合わせ満たし、より大きい$ I $ $ \ FRAC {N} {組み合わせ集電点か否かを判断します2} $缶。
#include <iostreamの> する#include <cstdioを> の#define MAX_N(1,000 + 5)を使用して名前空間STDを、int型のn; INT [MAX_N] [MAX_N]、L [MAX_N]。 INT R [MAX_N]、[MAX_N] C。INTルート(INT X) { int型 R = X、TMP。 一方、(R = R [R]!)R = R [R]。 ながら(!X = R [X])TMP = R [X]、R [x]はR、X = = TMPと、 返すRを。 } ボイドマージ(int型のx、int型のY) { X = ルート(X) Y =ルート(Y)。 R [X] = Y。 C [Y] + = C [X]。 C [X] = 0 ; 返します。 } int型のmain() { scanf関数(" %のD "、&N) 用(登録をint i = 1 ; iが<= N; ++ i)が { scanf関数(" %のD "はL + I)。 用(登録INT J = 1 ; J <= 1 [I] ++ J) { のscanf(" %dの"、[I] + J); } } ため(登録をint i = 1 iが<= N; ++ I) { 式中、Rは[I] = I; C [I] = 1 ; } ため(登録int型 Iを= N; I; - i)が { ため(登録INT J = 1 ; jは<= 1 [I]; ++ j)は { 場合(I> [I] [J])を続行; 場合(ルート(I !)=場合ルート([I] [J]))マージ(I、[I] [J])。 (C [ルート(I)]>(N >> 1)) 、戻りのprintf(" %dの"、I)、0 。 } } 戻り 0 。 }