树叶子节点
# include <iostream>
# include <algorithm>
# include <cstring>
using namespace std;
const int N = 110 ;
int head[ N] , e[ N] , ne[ N] , idx;
int n, m;
void add ( int a, int b)
{
e[ idx] = b;
ne[ idx] = head[ a] ;
head[ a] = idx;
idx++ ;
}
int max_depth;
int node_num[ N] ;
void dfs ( int node, int depth)
{
if ( head[ node] == - 1 ) {
node_num[ depth] ++ ;
max_depth = max ( depth, max_depth) ;
return ;
}
for ( int i= head[ node] ; i!= - 1 ; i= ne[ i] ) {
dfs ( e[ i] , depth+ 1 ) ;
}
}
int main ( )
{
cin >> n >> m;
memset ( head, - 1 , sizeof head) ;
while ( m-- )
{
int id, k;
cin >> id >> k;
while ( k-- ) {
int num;
cin >> num;
add ( id, num) ;
}
}
dfs ( 1 , 0 ) ;
for ( int i= 0 ; i<= max_depth; i++ ) cout << node_num[ i] << " " ;
return 0 ;
}
树的遍历
map的一些操作
map操作参考
# include <map>
# include <iostream>
# include <string>
using namespace std;
map< int , string> ID_Name = {
{ 2015 , "Jim" } ,
{ 2016 , "Tom" } ,
{ 2017 , "Bob" } } ;
int main ( )
{
cout << ID_Name[ 2015 ] << endl;
ID_Name[ 2020 ] = "ning" ;
cout << ID_Name[ 2020 ] << endl;
for ( map< int , string> :: iterator it = ID_Name. begin ( ) ; it!= ID_Name. end ( ) ; it++ ) {
cout << it-> first << ":" << it-> second << endl;
}
cout << ID_Name. count ( 2021 ) ;
return 0 ;
}
题目
# include <iostream>
# include <algorithm>
# include <map>
# include <queue>
using namespace std;
const int N = 40 ;
int inorder[ N] , postorder[ N] ;
map< int , int > left_child, right_child, position;
int build ( int in_l, int in_r, int post_l, int post_r)
{
int root = postorder[ post_r] ;
int pos = position[ root] ;
if ( in_l < position[ root] ) left_child[ root] = build ( in_l, pos- 1 , post_l, post_l+ pos- 1 - in_l) ;
if ( in_r > position[ root] ) right_child[ root] = build ( pos+ 1 , in_r, post_r- 1 - ( in_r- pos- 1 ) , post_r- 1 ) ;
return root;
}
int main ( )
{
int n;
cin >> n;
for ( int i= 0 ; i< n; i++ ) cin >> postorder[ i] ;
for ( int i= 0 ; i< n; i++ ) {
cin >> inorder[ i] ;
position[ inorder[ i] ] = i;
}
int root = build ( 0 , n- 1 , 0 , n- 1 ) ;
queue< int > q;
q. push ( root) ;
while ( ! q. empty ( ) ) {
int node = q. front ( ) ;
if ( left_child. count ( node) ) q. push ( left_child[ node] ) ;
if ( right_child. count ( node) ) q. push ( right_child[ node] ) ;
cout << node << " " ;
q. pop ( ) ;
}
return 0 ;
}
dfs另一种写法
# include <iostream>
# include <algorithm>
# include <cstring>
# include <queue>
# include <map>
using namespace std;
const int N = 40 ;
int postorder[ N] , inorder[ N] ;
int n;
map< int , int > left_child, right_child, pos;
int dfs ( int inl, int inr, int postl, int postr)
{
if ( inl > inr) return 0 ;
int root = postorder[ postr] ;
int p = pos[ root] ;
left_child[ root] = dfs ( inl, p- 1 , postl, postl+ p- 1 - inl) ;
right_child[ root] = dfs ( p+ 1 , inr, postr- 1 - ( inr- p- 1 ) , postr- 1 ) ;
return root;
}
int main ( )
{
cin >> n;
for ( int i= 0 ; i< n; i++ ) cin >> postorder[ i] ;
for ( int i= 0 ; i< n; i++ ) {
cin >> inorder[ i] ;
pos[ inorder[ i] ] = i;
}
int root = dfs ( 0 , n- 1 , 0 , n- 1 ) ;
queue< int > q;
q. push ( root) ;
while ( ! q. empty ( ) )
{
int node = q. front ( ) ;
q. pop ( ) ;
if ( left_child[ node] ) q. push ( left_child[ node] ) ;
if ( right_child[ node] ) q. push ( right_child[ node] ) ;
cout << node << " " ;
}
return 0 ;
}
再次树遍历
# include <iostream>
# include <algorithm>
# include <map>
# include <stack>
using namespace std;
const int N = 40 ;
int n;
int preorder[ N] ;
int inorder[ N] ;
map< int , int > left_child, right_child, pos;
int build ( int pre_l, int pre_r, int in_l, int in_r)
{
int root = preorder[ pre_l] ;
int pos_in = pos[ root] ;
if ( pos_in > in_l) left_child[ root] = build ( pre_l + 1 , pre_l + pos_in - in_l , in_l, pos_in- 1 ) ;
if ( pos_in < in_r) right_child[ root] = build ( pos_in + pre_l + 1 - in_l, pre_r, pos_in+ 1 , in_r) ;
return root;
}
void postorder ( int node)
{
int now_node = node;
if ( left_child. count ( now_node) != 0 ) postorder ( left_child[ now_node] ) ;
if ( right_child. count ( now_node) != 0 ) postorder ( right_child[ now_node] ) ;
cout << now_node << " " ;
}
int main ( )
{
cin >> n;
int m = 2 * n;
stack< int > st;
int i = 0 , j = 0 ;
while ( m-- ) {
string s;
cin >> s;
if ( s== "Push" ) {
int num;
cin >> num;
st. push ( num) ;
preorder[ i++ ] = num;
}
else if ( s== "Pop" ) {
int num = st. top ( ) ;
st. pop ( ) ;
inorder[ j] = num;
pos[ num] = j;
j++ ;
}
}
int root = build ( 0 , n- 1 , 0 , n- 1 ) ;
postorder ( root) ;
return 0 ;
}
最深的根
# include <cstring>
# include <iostream>
# include <algorithm>
# include <vector>
using namespace std;
const int N = 1e4 + 10 ;
const int M = 2 * N;
int n;
int e[ M] , ne[ M] , h[ M] , idx;
void add ( int a, int b)
{
e[ idx] = b;
ne[ idx] = h[ a] ;
h[ a] = idx;
idx++ ;
}
int p[ M] ;
int find ( int x)
{
if ( p[ x] != x) p[ x] = find ( p[ x] ) ;
return p[ x] ;
}
int dfs ( int u, int father)
{
int depth = 0 ;
for ( int i= h[ u] ; i!= - 1 ; i= ne[ i] )
{
if ( e[ i] == father) continue ;
depth = max ( depth, dfs ( e[ i] , u) + 1 ) ;
}
return depth;
}
int main ( )
{
cin >> n;
memset ( h, - 1 , sizeof h) ;
for ( int i= 1 ; i<= n; i++ ) p[ i] = i;
int k = n;
for ( int i= 0 ; i< n- 1 ; i++ ) {
int a, b;
cin >> a >> b;
add ( a, b) , add ( b, a) ;
if ( find ( a) != find ( b) ) {
p[ find ( a) ] = find ( b) ;
k-- ;
}
}
if ( k> 1 ) printf ( "Error: %d components" , k) ;
else {
vector< int > res;
int max_depth = - 1 ;
for ( int i= 1 ; i<= n; i++ ) {
int now_depth = dfs ( i, - 1 ) ;
if ( now_depth > max_depth) {
max_depth = now_depth;
res. clear ( ) ;
res. push_back ( i) ;
}
else if ( now_depth == max_depth) res. push_back ( i) ;
}
for ( auto i: res) cout << i << endl;
}
return 0 ;
}
判断二叉搜索树
# include <iostream>
# include <algorithm>
# include <cstring>
using namespace std;
const int N = 1010 ;
int n;
int preorder[ N] , inorder[ N] ;
int postorder[ N] , cnt = 0 ;
bool build ( int inl, int inr, int prel, int prer, int type)
{
if ( inl > inr) return true ;
int root = preorder[ prel] ;
int k;
if ( type== 0 ) {
for ( k= inl; k<= inr; k++ ) {
if ( inorder[ k] == root) break ;
}
if ( k> inr) return false ;
}
else {
for ( k= inr; k>= inl; k-- ) {
if ( inorder[ k] == root) break ;
}
if ( k< inl) return false ;
}
bool res = true ;
if ( ! build ( inl, k- 1 , prel+ 1 , prel+ 1 + ( k- 1 - inl) , type) ) res = false ;
if ( ! build ( k+ 1 , inr, prel + 1 + ( k - 1 - inl) + 1 , prer, type) ) res = false ;
postorder[ cnt] = root;
cnt ++ ;
return res;
}
int main ( )
{
cin >> n;
for ( int i= 0 ; i< n; i++ ) {
cin >> preorder[ i] ;
inorder[ i] = preorder[ i] ;
}
sort ( inorder, inorder+ n) ;
if ( build ( 0 , n- 1 , 0 , n- 1 , 0 ) ) {
cout << "YES" << endl;
for ( int i= 0 ; i< n; i++ ) cout << postorder[ i] << " " ;
}
else {
cnt = 0 ;
reverse ( inorder, inorder+ n) ;
if ( build ( 0 , n- 1 , 0 , n- 1 , 1 ) ) {
cout << "YES" << endl;
for ( int i= 0 ; i< n; i++ ) cout << postorder[ i] << " " ;
}
else cout << "NO" ;
}
return 0 ;
}
完全二叉搜索树
# include <iostream>
# include <algorithm>
# include <cstring>
using namespace std;
const int N = 1010 ;
int w[ N] , tree[ N] ;
int n;
int k = 0 ;
void dfs ( int u, int & k) {
if ( u* 2 <= n) dfs ( u* 2 , k) ;
tree[ u] = w[ k] ;
k++ ;
if ( ( u* 2 + 1 ) <= n) dfs ( u* 2 + 1 , k) ;
}
int main ( )
{
cin >> n;
for ( int i= 0 ; i< n; i++ ) cin >> w[ i] ;
sort ( w, w+ n) ;
dfs ( 1 , k) ;
for ( int i= 1 ; i<= n; i++ ) cout << tree[ i] << " " ;
return 0 ;
}
构建二叉搜索树
# include <iostream>
# include <algorithm>
# include <cstring>
# include <queue>
using namespace std;
const int N = 110 ;
int n;
int left_child[ N] , right_child[ N] ;
int tree[ N] , k = 0 ;
int w[ N] ;
void dfs ( int u, int & k)
{
if ( u== - 1 ) return ;
dfs ( left_child[ u] , k) ;
tree[ u] = w[ k++ ] ;
dfs ( right_child[ u] , k) ;
}
int main ( )
{
cin >> n;
for ( int i= 0 ; i< n; i++ ) {
int l, r;
cin >> l >> r;
left_child[ i] = l;
right_child[ i] = r;
}
for ( int i= 0 ; i< n; i++ ) cin >> w[ i] ;
sort ( w, w+ n) ;
dfs ( 0 , k) ;
queue< int > q;
q. push ( 0 ) ;
while ( ! q. empty ( ) ) {
int node = q. front ( ) ;
q. pop ( ) ;
if ( left_child[ node] != - 1 ) q. push ( left_child[ node] ) ;
if ( right_child[ node] != - 1 ) q. push ( right_child[ node] ) ;
cout << tree[ node] << " " ;
}
return 0 ;
}
反转二叉树
# include <iostream>
# include <algorithm>
# include <cstring>
# include <queue>
using namespace std;
const int N = 20 ;
int n;
int left_child[ N] , right_child[ N] ;
bool has_father[ N] ;
void dfs ( int u)
{
if ( u== - 1 ) return ;
dfs ( right_child[ u] ) ;
cout << u << " " ;
dfs ( left_child[ u] ) ;
}
int main ( )
{
cin >> n;
memset ( left_child, - 1 , sizeof left_child) ;
memset ( right_child, - 1 , sizeof right_child) ;
for ( int i= 0 ; i< n; i++ ) {
char l, r;
cin >> l >> r;
if ( l!= '-' ) {
left_child[ i] = l - '0' ;
has_father[ left_child[ i] ] = true ;
}
if ( r!= '-' ) {
right_child[ i] = r - '0' ;
has_father[ right_child[ i] ] = true ;
}
}
int root = 0 ;
while ( has_father[ root] ) root++ ;
queue< int > q;
q. push ( root) ;
while ( ! q. empty ( ) )
{
int node = q. front ( ) ;
q. pop ( ) ;
if ( right_child[ node] != - 1 ) q. push ( right_child[ node] ) ;
if ( left_child[ node] != - 1 ) q. push ( left_child[ node] ) ;
cout << node << " " ;
}
cout << endl;
dfs ( root) ;
return 0 ;
}
完全二叉树
# include <algorithm>
# include <iostream>
# include <cstring>
using namespace std;
const int N = 30 ;
int n;
int l[ N] , r[ N] ;
bool has_father[ N] ;
int lastid, maxk = 0 ;
void dfs ( int u, int k)
{
if ( u== - 1 ) return ;
if ( k > maxk) {
lastid = u;
maxk = k;
}
if ( l[ u] != - 1 ) dfs ( l[ u] , 2 * k) ;
if ( r[ u] != - 1 ) dfs ( r[ u] , 2 * k+ 1 ) ;
}
int main ( )
{
cin >> n;
memset ( l, - 1 , sizeof l) ;
memset ( r, - 1 , sizeof r) ;
for ( int i= 0 ; i< n; i++ ) {
string a, b;
cin >> a >> b;
if ( a!= "-" ) {
l[ i] = stoi ( a) ;
has_father[ l[ i] ] = true ;
}
if ( b!= "-" ) {
r[ i] = stoi ( b) ;
has_father[ r[ i] ] = true ;
}
}
int root = 0 ;
while ( has_father[ root] ) root++ ;
dfs ( root, 1 ) ;
if ( maxk== n) {
cout << "YES " << lastid << endl;
}
else cout << "NO " << root << endl;
return 0 ;
}
二叉搜索树最后两层节点数量
# include <algorithm>
# include <iostream>
using namespace std;
const int N = 1010 ;
int left_child[ N] , right_child[ N] ;
int a[ N] ;
int n;
int idx = 0 ;
void insert ( int & u, int value)
{
if ( u== 0 ) {
idx++ ;
u = idx;
}
else if ( a[ u] >= value) insert ( left_child[ u] , value) ;
else insert ( right_child[ u] , value) ;
}
int level[ N] , max_depth = - 1 ;
void dfs ( int u, int depth)
{
if ( u== 0 ) return ;
level[ depth] ++ ;
max_depth = max ( max_depth, depth) ;
dfs ( left_child[ u] , depth+ 1 ) ;
dfs ( right_child[ u] , depth+ 1 ) ;
}
int main ( )
{
cin >> n;
for ( int i= 1 ; i<= n; i++ ) {
int w;
cin >> w;
a[ i] = w;
}
int root = 0 ;
for ( int i= 1 ; i<= n; i++ ) insert ( root, a[ i] ) ;
dfs ( root, 1 ) ;
int n1 = level[ max_depth] ;
int n2 = level[ max_depth- 1 ] ;
printf ( "%d + %d = %d" , n1, n2, n1+ n2) ;
return 0 ;
}
前序和后序遍历
# include <algorithm>
# include <iostream>
# include <cstring>
using namespace std;
const int N = 40 ;
int n;
int pre[ N] , post[ N] ;
int build ( int prel, int prer, int postl, int postr, string& res)
{
if ( prel > prer) return 1 ;
if ( pre[ prel] != post[ postr] ) return 0 ;
int cnt = 0 ;
for ( int i= prel; i<= prer; i++ ) {
string res_left, res_right;
int cnt1 = build ( prel+ 1 , i, postl, postl+ i- prel- 1 , res_left) ;
int cnt2 = build ( i+ 1 , prer, postl+ i- prel, postr- 1 , res_right) ;
if ( cnt1 && cnt2) {
cnt += cnt1* cnt2;
res = res_left + to_string ( pre[ prel] ) + " " + res_right;
if ( cnt > 1 ) break ;
}
}
return cnt;
}
int main ( )
{
cin >> n;
for ( int i= 0 ; i< n; i++ ) cin >> pre[ i] ;
for ( int i= 0 ; i< n; i++ ) cin >> post[ i] ;
string res;
int cnt = build ( 0 , n- 1 , 0 , n- 1 , res) ;
if ( cnt > 1 ) puts ( "No" ) ;
else puts ( "Yes" ) ;
res. pop_back ( ) ;
cout << res;
return 0 ;
}
Z字形遍历二叉树
# include <iostream>
# include <algorithm>
# include <queue>
# include <map>
using namespace std;
const int N = 40 ;
int n;
int inorder[ N] , postorder[ N] ;
map< int , int > left_child, right_child, pos;
int build ( int inl, int inr, int postl, int postr)
{
int root = postorder[ postr] ;
int k = pos[ root] ;
if ( inl < k) left_child[ root] = build ( inl, k- 1 , postl, postl+ k- 1 - inl) ;
if ( inr > k) right_child[ root] = build ( k+ 1 , inr, postr- inr+ k, postr- 1 ) ;
return root;
}
int main ( )
{
cin >> n;
for ( int i= 0 ; i< n; i++ ) {
cin >> inorder[ i] ;
pos[ inorder[ i] ] = i;
}
for ( int i= 0 ; i< n; i++ ) cin >> postorder[ i] ;
int root = build ( 0 , n- 1 , 0 , n- 1 ) ;
int q[ N] ;
q[ 0 ] = root;
int hh = 0 , tt = 0 ;
int level = 0 ;
while ( hh <= tt)
{
int head = hh;
int tail = tt;
while ( hh <= tail)
{
int now_node = q[ hh++ ] ;
if ( left_child. count ( now_node) ) q[ ++ tt] = left_child[ now_node] ;
if ( right_child. count ( now_node) ) q[ ++ tt] = right_child[ now_node] ;
}
level++ ;
if ( level % 2 == 1 ) reverse ( q+ head, q+ tail+ 1 ) ;
}
cout << q[ 0 ] ;
for ( int i= 1 ; i<= tt; i++ ) cout<< " " << q[ i] ;
return 0 ;
}
后序遍历
# include <iostream>
# include <algorithm>
# include <map>
using namespace std;
const int N = 50010 ;
int n;
int preorder[ N] , inorder[ N] ;
int postorder[ N] , idx = 0 ;
map< int , int > left_child, right_child, pos;
int build ( int prel, int prer, int inl, int inr)
{
int root = preorder[ prel] ;
int k = pos[ root] ;
if ( inl < k) left_child[ root] = build ( prel+ 1 , prel+ 1 + k- 1 - inl, inl, k- 1 ) ;
if ( inr > k) right_child[ root] = build ( prer- ( inr- k- 1 ) , prer, k+ 1 , inr) ;
return root;
}
void dfs ( int u)
{
if ( u== 0 ) return ;
dfs ( left_child[ u] ) ;
dfs ( right_child[ u] ) ;
postorder[ idx++ ] = u;
}
int main ( )
{
cin >> n;
for ( int i= 0 ; i< n; i++ ) cin >> preorder[ i] ;
for ( int i= 0 ; i< n; i++ ) {
cin >> inorder[ i] ;
pos[ inorder[ i] ] = i;
}
int root = build ( 0 , n- 1 , 0 , n- 1 ) ;
dfs ( root) ;
cout << postorder[ 0 ] << endl;
return 0 ;
}
PAT1053等重路径
# include <algorithm>
# include <iostream>
# include <cstring>
# include <vector>
using namespace std;
const int N = 110 ;
bool g[ N] [ N] ;
int n, m, s;
int w[ N] ;
bool leaf[ N] ;
vector< vector< int >> res;
void dfs ( int u, int weight, vector< int > & path)
{
if ( leaf[ u] ) {
if ( weight== s) res. push_back ( path) ;
return ;
}
for ( int i= 0 ; i< n; i++ ) {
if ( g[ u] [ i] ) {
path. push_back ( w[ i] ) ;
dfs ( i, weight+ w[ i] , path) ;
path. pop_back ( ) ;
}
}
}
int main ( )
{
cin >> n >> m >> s;
for ( int i= 0 ; i< n; i++ ) cin >> w[ i] ;
for ( int i= 0 ; i< n; i++ ) leaf[ i] = true ;
while ( m-- )
{
int id, k;
cin >> id >> k;
leaf[ id] = false ;
while ( k-- )
{
int son;
cin >> son;
g[ id] [ son] = true ;
}
}
vector< int > path;
path. push_back ( w[ 0 ] ) ;
dfs ( 0 , w[ 0 ] , path) ;
sort ( res. begin ( ) , res. end ( ) , greater< vector< int >> ( ) ) ;
for ( int i= 0 ; i< res. size ( ) ; i++ ) {
for ( int j= 0 ; j< res[ i] . size ( ) ; j++ ) cout << res[ i] [ j] << " " ;
cout << endl;
}
return 0 ;
}
最大的一代
# include <algorithm>
# include <iostream>
# include <map>
# include <vector>
# include <cstring>
using namespace std;
const int N = 1100 ;
int n, m;
int e[ N] , ne[ N] , h[ N] , idx;
void add ( int a, int b)
{
e[ idx] = b;
ne[ idx] = h[ a] ;
h[ a] = idx;
idx++ ;
}
int depth[ N] ;
int max_depth = - 1 ;
void dfs ( int u, int d)
{
if ( u== - 1 ) return ;
depth[ d] ++ ;
max_depth = max ( max_depth, d) ;
for ( int i= h[ u] ; i!= - 1 ; i= ne[ i] )
{
int j = e[ i] ;
dfs ( j, d+ 1 ) ;
}
}
int main ( )
{
cin >> n >> m;
memset ( h, - 1 , sizeof h) ;
while ( m-- )
{
int father, k;
cin >> father >> k;
while ( k-- ) {
int son;
cin >> son;
add ( father, son) ;
}
}
dfs ( 1 , 1 ) ;
int max_node = - 1 ;
int level = 1 ;
for ( int i= 1 ; i<= max_depth; i++ ) {
if ( depth[ i] > max_node) {
max_node = depth[ i] ;
level = i;
}
}
cout << max_node << " " << level << endl;
return 0 ;
}
供应链总销售额
# include <iostream>
# include <algorithm>
# include <cstring>
using namespace std;
const int N = 1e5 + 10 ;
int n;
double p, r;
int e[ N] , ne[ N] , h[ N] , idx;
bool leaf[ N] ;
int item_num[ N] ;
void add ( int a, int b)
{
e[ idx] = b;
ne[ idx] = h[ a] ;
h[ a] = idx;
idx++ ;
}
double total_sum = 0 ;
void dfs ( int u, double price)
{
if ( leaf[ u] ) {
total_sum += price * item_num[ u] ;
return ;
}
for ( int i= h[ u] ; i!= - 1 ; i= ne[ i] ) {
int j = e[ i] ;
dfs ( j, price* ( 1 + r/ 100 ) ) ;
}
}
int main ( )
{
cin >> n >> p >> r;
memset ( h, - 1 , sizeof h) ;
for ( int i= 0 ; i< n; i++ ) leaf[ i] = false ;
for ( int i= 0 ; i< n; i++ ) {
int k;
cin >> k;
if ( k== 0 ) {
leaf[ i] = true ;
cin >> item_num[ i] ;
}
else {
while ( k-- ) {
int id;
cin >> id;
add ( i, id) ;
}
}
}
dfs ( 0 , p) ;
printf ( "%.1lf" , total_sum) ;
return 0 ;
}
供应链最高价格
# include <algorithm>
# include <cstring>
# include <iostream>
# include <queue>
using namespace std;
const int N = 1e5 + 10 ;
int n;
double p, r;
int e[ N] , ne[ N] , h[ N] , idx;
bool leaf[ N] ;
void add ( int a, int b)
{
e[ idx] = b;
ne[ idx] = h[ a] ;
h[ a] = idx;
idx++ ;
}
int node_num[ N] ;
int max_depth = - 1 ;
double cost[ N] ;
void dfs ( int u, int d, double price)
{
if ( u== - 1 ) return ;
if ( leaf[ u] ) {
max_depth = max ( max_depth, d) ;
node_num[ d] ++ ;
cost[ d] = price;
return ;
}
for ( int i= h[ u] ; i!= - 1 ; i= ne[ i] ) {
int j = e[ i] ;
dfs ( j, d+ 1 , price* ( 1 + r/ 100 ) ) ;
}
}
int main ( )
{
memset ( h, - 1 , sizeof h) ;
cin >> n >> p >> r;
int root;
for ( int i= 0 ; i< n; i++ ) {
int father;
cin >> father;
if ( father== - 1 ) {
root = i;
}
else {
add ( father, i) ;
}
}
for ( int i= 0 ; i< n; i++ ) leaf[ i] = false ;
for ( int i= 0 ; i< n; i++ ) {
if ( h[ i] == - 1 ) leaf[ i] = true ;
}
dfs ( root, 1 , p) ;
printf ( "%.2lf %d" , cost[ max_depth] , node_num[ max_depth] ) ;
return 0 ;
}
供应链最低价格
# include <algorithm>
# include <iostream>
# include <cstring>
# include <queue>
using namespace std;
const int N = 1e5 + 10 ;
int n;
double p, r;
int e[ N] , ne[ N] , h[ N] , idx;
bool leaf[ N] ;
void add ( int a, int b)
{
e[ idx] = b;
ne[ idx] = h[ a] ;
h[ a] = idx;
idx++ ;
}
int max_depth = - 1 ;
int node_num[ N] ;
double cost[ N] ;
void dfs ( int u, int d, double price)
{
if ( leaf[ u] ) {
max_depth = d;
node_num[ d] ++ ;
cost[ d] = price;
}
for ( int i= h[ u] ; i!= - 1 ; i= ne[ i] )
{
int j = e[ i] ;
dfs ( j, d+ 1 , price * ( 1 + r/ 100 ) ) ;
}
}
int main ( )
{
memset ( h, - 1 , sizeof h) ;
cin >> n >> p >> r;
for ( int i= 0 ; i< n; i++ ) leaf[ i] = false ;
for ( int i= 0 ; i< n; i++ ) {
int k;
cin >> k;
if ( k== 0 ) {
leaf[ i] = true ;
}
else {
while ( k-- ) {
int son;
cin >> son;
add ( i, son) ;
}
}
}
dfs ( 0 , 1 , p) ;
int min_depth = 0 ;
for ( int i= 1 ; i<= max_depth; i++ ) {
if ( node_num[ i] ) {
min_depth = i;
break ;
}
}
printf ( "%.4lf %d" , cost[ min_depth] , node_num[ min_depth] ) ;
return 0 ;
}
堆路径
# include <algorithm>
# include <iostream>
# include <cstring>
# include <vector>
using namespace std;
const int N = 1010 ;
int heap[ N] ;
int n;
vector< vector< int >> res;
vector< int > path;
void dfs ( int u)
{
path. push_back ( heap[ u] ) ;
if ( 2 * u > n) {
res. push_back ( path) ;
path. pop_back ( ) ;
return ;
}
if ( ( 2 * u+ 1 ) <= n) dfs ( 2 * u+ 1 ) ;
if ( 2 * u <= n) dfs ( 2 * u) ;
path. pop_back ( ) ;
}
int main ( )
{
cin >> n;
for ( int i= 1 ; i<= n; i++ ) cin >> heap[ i] ;
dfs ( 1 ) ;
for ( int i= 0 ; i< res. size ( ) ; i++ ) {
cout << res[ i] [ 0 ] ;
for ( int j= 1 ; j< res[ i] . size ( ) ; j++ ) {
cout << " " << res[ i] [ j] ;
}
cout << endl;
}
bool if_max_heap = true ;
bool if_min_heap = true ;
for ( int i= 0 ; i< res. size ( ) ; i++ ) {
for ( int j= 1 ; j< res[ i] . size ( ) ; j++ ) {
if ( res[ i] [ j] < res[ i] [ j- 1 ] ) {
if_min_heap = false ;
break ;
}
}
}
for ( int i= 0 ; i< res. size ( ) ; i++ ) {
for ( int j= 1 ; j< res[ i] . size ( ) ; j++ ) {
if ( res[ i] [ j] > res[ i] [ j- 1 ] ) {
if_max_heap = false ;
break ;
}
}
}
if ( ! if_min_heap && ! if_max_heap) cout << "Not Heap" << endl;
else if ( if_min_heap) cout << "Min Heap" << endl;
else if ( if_max_heap) cout << "Max Heap" << endl;
return 0 ;
}
中缀表达式
# include <algorithm>
# include <iostream>
# include <cstring>
# include <vector>
using namespace std;
const int N = 30 ;
int n;
bool has_father[ N] ;
string v[ N] ;
int l[ N] , r[ N] ;
bool leaf[ N] ;
int root;
vector< string> res;
void dfs ( int u)
{
if ( u== 0 ) return ;
if ( ! leaf[ u] && u!= root) res. push_back ( "(" ) ;
dfs ( l[ u] ) ;
res. push_back ( v[ u] ) ;
dfs ( r[ u] ) ;
if ( ! leaf[ u] && u!= root) res. push_back ( ")" ) ;
}
int main ( )
{
cin >> n;
for ( int i= 1 ; i<= n; i++ ) {
cin >> v[ i] ;
int a, b;
cin >> a >> b;
if ( a== - 1 && b== - 1 ) leaf[ i] = true ;
if ( a!= - 1 ) {
l[ i] = a;
has_father[ a] = true ;
}
if ( b!= - 1 ) {
r[ i] = b;
has_father[ b] = true ;
}
}
for ( int i= 1 ; i<= n; i++ ) {
if ( ! has_father[ i] ) root = i;
}
dfs ( root) ;
for ( int i= 0 ; i< res. size ( ) ; i++ ) cout << res[ i] ;
return 0 ;
}
最低公共祖先
# include <algorithm>
# include <iostream>
# include <cstring>
# include <map>
using namespace std;
const int N = 10010 ;
int m, n;
int inorder[ N] , preorder[ N] , seq[ N] ;
map< int , int > pos;
int parent[ N] ;
int depth[ N] ;
int build ( int inl, int inr, int prel, int prer, int d)
{
int root = preorder[ prel] ;
depth[ root] = d;
int k = root;
if ( inl < k) parent[ build ( inl, k- 1 , prel+ 1 , prel+ 1 + k- 1 - inl, d+ 1 ) ] = root;
if ( inr > k) parent[ build ( k+ 1 , inr, prer- ( inr- k- 1 ) , prer, d+ 1 ) ] = root;
return root;
}
int main ( )
{
cin >> m >> n;
for ( int i= 0 ; i< n; i++ ) {
cin >> preorder[ i] ;
seq[ i] = preorder[ i] ;
}
sort ( seq, seq+ n) ;
for ( int i= 0 ; i< n; i++ ) {
inorder[ i] = i;
pos[ seq[ i] ] = i;
}
for ( int i= 0 ; i< n; i++ ) preorder[ i] = pos[ preorder[ i] ] ;
int root = build ( 0 , n- 1 , 0 , n- 1 , 0 ) ;
while ( m -- )
{
int a, b;
cin >> a >> b;
if ( pos. count ( a) && pos. count ( b) )
{
a = pos[ a] , b = pos[ b] ;
int x = a, y = b;
while ( a != b)
if ( depth[ a] < depth[ b] ) b = parent[ b] ;
else a = parent[ a] ;
if ( a != x && a != y) printf ( "LCA of %d and %d is %d.\n" , seq[ x] , seq[ y] , seq[ a] ) ;
else if ( a == x) printf ( "%d is an ancestor of %d.\n" , seq[ x] , seq[ y] ) ;
else printf ( "%d is an ancestor of %d.\n" , seq[ y] , seq[ x] ) ;
}
else if ( pos. count ( a) == 0 && pos. count ( b) == 0 )
printf ( "ERROR: %d and %d are not found.\n" , a, b) ;
else if ( pos. count ( a) == 0 )
printf ( "ERROR: %d is not found.\n" , a) ;
else
printf ( "ERROR: %d is not found.\n" , b) ;
}
return 0 ;
}
二叉树中的最低公共祖先
# include <algorithm>
# include <iostream>
# include <cstring>
# include <map>
using namespace std;
const int N = 10010 ;
int m, n;
int preorder[ N] , inorder[ N] , seq[ N] ;
map< int , int > pos;
int depth[ N] , parent[ N] ;
int build ( int inl, int inr, int prel, int prer, int d)
{
int root = preorder[ prel] ;
int k = root;
depth[ root] = d;
if ( inl < k) parent[ build ( inl, k- 1 , prel+ 1 , prel+ 1 + k- 1 - inl, d+ 1 ) ] = root;
if ( inr > k) parent[ build ( k+ 1 , inr, prer- ( inr- k- 1 ) , prer, d+ 1 ) ] = root;
return root;
}
int main ( )
{
cin >> m >> n;
for ( int i= 0 ; i< n; i++ ) {
cin >> inorder[ i] ;
seq[ i] = inorder[ i] ;
pos[ inorder[ i] ] = i;
inorder[ i] = i;
}
for ( int i= 0 ; i< n; i++ ) {
cin >> preorder[ i] ;
preorder[ i] = pos[ preorder[ i] ] ;
}
int root = build ( 0 , n- 1 , 0 , n- 1 , 0 ) ;
while ( m-- )
{
int u, v;
cin >> u >> v;
if ( pos. count ( u) && pos. count ( v) )
{
int x = pos[ u] , y = pos[ v] ;
int a = x, b = y;
while ( x != y) {
if ( depth[ x] < depth[ y] ) y = parent[ y] ;
else x = parent[ x] ;
}
if ( x!= a && x!= b) printf ( "LCA of %d and %d is %d.\n" , u, v, seq[ x] ) ;
else if ( x== a) printf ( "%d is an ancestor of %d.\n" , u, v) ;
else printf ( "%d is an ancestor of %d.\n" , v, u) ;
}
else if ( pos. count ( u) && pos. count ( v) == 0 ) printf ( "ERROR: %d is not found.\n" , v) ;
else if ( pos. count ( u) == 0 && pos. count ( v) ) printf ( "ERROR: %d is not found.\n" , u) ;
else printf ( "ERROR: %d and %d are not found.\n" , u, v) ;
}
return 0 ;
}