POJ 1655 Balancing Act (dfs)

题意:给定一棵树,问拿掉那个点,能使余下的各个子树结点个数上限最小。

看了半天,只知道是深搜,可是想了很久也没想出实现方法,各种菜~~~~看了大牛的实现,才恍然大悟........dfs的灵活之处自己需要时间去掌握啊.

 

  
    
#include < iostream >
#include
< cstdio >
#include
< algorithm >
#include
< memory.h >
#include
< cmath >
#include
< set >
#include
< queue >
#include
< vector >
using namespace std;

const int BORDER = ( 1 << 20 ) - 1 ;
#define MAXN 20020
#define INF 0x7ffffff
#define CLR(x,y) memset(x,y,sizeof(x))
#define ADD(x) ((++x)&BORDER)
#define IN(x) scanf("%d",&x)
#define OUT(x) printf("%d\n",x)
#define MIN(m,v) (m)<(v)?(m):(v)
#define MAX(m,v) (m)>(v)?(m):(v)
#define ABS(x) (x>0?x:-x)

struct EDGE{
int v,next;
}edge[MAXN
* 2 ];
int n,m,cnt,mmin_index,mmin_cnt,index;
int net[MAXN],visit[MAXN];
void add_edge( const int & u, const int & v)
{
edge[index].v
= v;
edge[index].next
= net[u];
net[u]
= index;
++ index;
edge[index].v
= u;
edge[index].next
= net[v];
net[v]
= index;
++ index;
}
int init()
{
index
= 0 ;
mmin_index
= INF;
mmin_cnt
= INF;
CLR(net,
- 1 );
CLR(visit,
0 );
return 0 ;
}
int dfs( const int & u)
{
int i,v;
int mmax = 0 ;
int sum = 0 ;
visit[u]
= 1 ;
for (i = net[u]; i != - 1 ; i = edge[i].next)
{
v
= edge[i].v;
if ( ! visit[v])
{
int tmp = dfs(v);
mmax
= MAX(mmax,tmp);
sum
+= tmp;
}
}
mmax
= MAX(mmax,n - sum - 1 );
if (mmin_cnt >= mmax)
{
if (mmin_cnt == mmax && mmin_index < u)
;
else
{
mmin_cnt
= mmax;
mmin_index
= u;
}
}
return sum + 1 ;
}
int input()
{
int i,j,tmp,a,b;
IN(n);

tmp
= n - 1 ;
for (i = 0 ; i < tmp; ++ i)
{
scanf(
" %d %d " , & a, & b);
add_edge(a,b);
}
return 0 ;
}
int work()
{
dfs(
1 );
printf(
" %d %d\n " ,mmin_index,mmin_cnt);
return 0 ;
}

int main()
{
int i,j,tt,tmp;
IN(tt);
while (tt -- )
{
init();
     input();

work();
}
return 0 ;
}

 

你可能感兴趣的:(poj)