タイトル説明
暁明は、Aドラゴンの村で、彼がいない侵入竜するために、村の平和を守るために持っています。そしてドラゴンが暁明を打つために、集団的攻撃を整理することを決めても、嫌わ暁明龍は、A村を獲得しました。暁明は龍が、互いの間の神秘的なリンクを作成する際に、集団攻撃を知って、そして竜の能力が成長することができ、相互そのようなリンクに接続され、各リンクに追加竜を持っています、すべてのドラゴンの能力内のリンクは、1を追加しますが、暁明ドラゴンよりも戦闘能力も大きくは竜を殺すために戦ったときのみ。幸いなことに、暁明は一回Tulongがあり、彼は竜を殺すために戦いを無視し、すべてのリンクの竜の体を排除することができます。各ドラゴン1にリンクされていないときの戦闘を想定、龍最初にすべて一緒にのみN N-1番目のリンクを接続します。ボブは、彼はすべてのドラゴンを殺すために、少なくとも戦闘力を持っている必要がありますどのくらい知っていただきたいと思います、と彼はTulongドラゴンに殺されるべきか疑問に思いました。
説明を入力します。
入力の最初の行は、整数N(1 <= N <= 40000)であり、Nは、長尺の合計を表します。次のラインN-1の整数(スペースで区切られた)、B、長い間のリンク関係を示します。
出力説明
スペースで区切って出力二つの整数。最初の整数Xは、ドラゴンはTulongが殺さアプリケーションの数を表します。いくつかのドラゴンはTulongを死滅させることができる場合、出力最小数、第2の整数Tは、暁明は、少なくともいくつかの戦闘を発現しました。
例
入力
。8
。1 2
2 3
15
。5。6
。6 8
2 4
5 7
の出力
15
問題解決のためのアイデア
例としては、最大のコレクション(ノードの数まで)、ノードを削除することである竜を殺した後、その後、近隣のノードの残りの部分は、ノードが複数のコレクションに分かれて殺され、シミュレーションについて説明していますドラゴンスレイヤーを持っている能力である少なくともノード数に1を加えました、。これは、最大のサブツリーのすべてのサブツリーの本質上のすべてのノードが必要です。
一つのノードがトラバースされる場合、最大のサブ・ツリーは、冗長演算の多数のために得られ、それが出あろう。最初のNによって明らか対象はN-1番目のリンクが一緒にエッジ以外に、有向グラフ、所定の方向に対応する(自分自身を指定した後、それは最初のツリーは、ルートノードとして見ることができるので、ノード図)は、深い検索が含まれ、追加さ方向として、直接サブツリーがシークする方法はありません各ノードの数(+1およびすべてのサブツリーの大きさ)のサブツリーのルートノードとして決定することができます子ノードのサイズが最大サブツリーがその上に記録された最小値を維持する過程において、サブツリーの残りの部分の大きさであるように、ツリーのルート-ノードの総数のうち。
実装コード
#include <iostream>
#include <vector>
#define NN 40010
using namespace std;
vector<vector<int> > Long(NN,vector<int>());
int n,maxn=NN,index_max=NN;
int getTreeSum(int index,int pre){
int len=Long[index].size();
int sum=0,maxv=0,subsum;
for(int i=0;i<len;i++)
if(Long[index][i]!=pre){
subsum=getTreeSum(Long[index][i],index);
if(subsum>maxv)
maxv=subsum;
sum+=subsum;
}
sum++;
int left=maxv;
if(n-sum>maxv)
left=n-sum;
if(maxn>left){
maxn=left;
index_max=index;
}else if(maxn==left&&index_max>index)
index_max=index;
return sum;
}
int main(){
cin>>n;
int a,b;
for(int i=1;i<n;i++){
cin>>a>>b;
Long[a].push_back(b);
Long[b].push_back(a);
}
getTreeSum(1,-1);
if(maxn!=0)
maxn++;
cout<<index_max<<" "<<maxn<<endl;
return 0;
}
最初は、この状態で一緒にリンクされているすべてのノードは、複雑さを軽減します、2または深い検索が必要です。