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;
}