您的位置:首页 > 编程语言 > Go语言

POJ 1655 Balancing Act && POJ 3107 Godfather

2015-01-19 14:41 429 查看
题目大意:

根据题目的图很好理解意思,就是记录每一个点的balance,例如 i 的balance就是把 i 从这棵树中除去后得到的森林中含有结点数最多

的子树中的节点个数,然后找到所有节点中对应的balance的最小值 , 并输出最小值对应的最小的标号

题目不要看花。。。前一个是找最大,后面找所有最大值中的最小,我就是看错一直wa,后来人家题解刚看完题目意思就反应过来 , 囧死了 - -

昨天貌似做过一道类似的题,任意找一点 , 比如 1 作为根进行dfs,第一次dfs记录所有点对应的子树中含有的节点的总个数

第二次dfs记录down[i] , 也就是i子树中 i 连接的所有子树中含有节点数最多的节点个数

其实down[i]就相当 i 出去后 , i 下方森林可得到的最大balance , 还需要求一个 i 上方的balance , 这个上方的值就是n-sum[i]

两者比较取最大就可以了

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
const int N = 20005;
int first
, k , sum
, down
, rec
;

struct Edge{
int y , next;
}e[N<<1];

void add_edge(int x , int y)
{
e[k].y = y , e[k].next = first[x];
first[x] = k++;
}

void dfs1(int u , int fa)
{
sum[u] = 1;
for(int i=first[u] ; i!=-1 ; i=e[i].next)
{
int v = e[i].y;
if(v == fa) continue;
dfs1(v , u);
sum[u] += sum[v];
}
}
void dfs2(int u , int fa)
{
for(int i=first[u] ; i!=-1 ; i=e[i].next)
{
int v = e[i].y;
if(v == fa) continue;
down[u] = max(sum[v]+1 , down[u]);
dfs2(v , u);
}
}

int main()
{
//  freopen("a.in" , "r" , stdin);
int T;
scanf("%d" , &T);
while(T--)
{
int n , a , b;
scanf("%d" , &n);
memset(first , -1 , sizeof(first));
k = 0;
for(int i=1 ; i<n ; i++){
scanf("%d%d" , &a , &b);
add_edge(a , b);
add_edge(b , a);
}
memset(down , 0 , sizeof(down));
dfs1(1 , -1);
dfs2(1 , -1);
int minn = down[1]-1;
rec[1] = down[1]-1;
//  cout<<"down: 1: "<<down[1]<<" "<<sum[1]<<endl;
for(int i=2 ; i<=n ; i++){
//    cout<<"down: i: "<<i<<" "<<" "<<down[i]<<" "<<sum[i]<<endl;
rec[i] = max(down[i]-1 , n-sum[i]);
minn = min(minn , rec[i]);
}
int i;
for(i=1 ; i<=n ; i++){
if(rec[i] == minn) break;
}
printf("%d %d\n" , i , minn);
}
return 0;
}


POJ 3107

求解问题的思想是和上面的题目是基本相同的,除了输入输出方式需要改变,然后数组开大点就可以照抄上面代码了

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
const int N = 50005;
int first
, k , sum
, down
, rec
;

struct Edge{
int y , next;
}e[N<<1];

void add_edge(int x , int y)
{
e[k].y = y , e[k].next = first[x];
first[x] = k++;
}

void dfs1(int u , int fa)
{
sum[u] = 1;
for(int i=first[u] ; i!=-1 ; i=e[i].next)
{
int v = e[i].y;
if(v == fa) continue;
dfs1(v , u);
sum[u] += sum[v];
}
}
void dfs2(int u , int fa)
{
for(int i=first[u] ; i!=-1 ; i=e[i].next)
{
int v = e[i].y;
if(v == fa) continue;
down[u] = max(sum[v]+1 , down[u]);
dfs2(v , u);
}
}

int main()
{
//  freopen("a.in" , "r" , stdin);
int n , a , b;
while(scanf("%d" , &n) == 1){
memset(first , -1 , sizeof(first));
k = 0;
for(int i=1 ; i<n ; i++){
scanf("%d%d" , &a , &b);
add_edge(a , b);
add_edge(b , a);
}
memset(down , 0 , sizeof(down));
dfs1(1 , -1);
dfs2(1 , -1);
int minn = down[1]-1;
rec[1] = down[1]-1;
//  cout<<"down: 1: "<<down[1]<<" "<<sum[1]<<endl;
for(int i=2 ; i<=n ; i++){
//    cout<<"down: i: "<<i<<" "<<" "<<down[i]<<" "<<sum[i]<<endl;
rec[i] = max(down[i]-1 , n-sum[i]);
minn = min(minn , rec[i]);
}
int num = 0;
for(int i=1 ; i<=n ; i++){
if(rec[i] == minn){
if(num == 0) printf("%d" , i);
else printf(" %d" , i);
num++;
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: