题目链接

虽然题目不难,但是1A还是很爽, 只是刚开始理解错题意了,想了好久。 还有据说这个题用vector会超时,看了以后还是用邻接吧。

题意:

给一颗树,保证是一颗树,求去掉一个点以后的联通块里节点的数目的 最大值最小,求这样的点,并按照递增顺序输出。

分析:

d[father] = max(n-sum, d[son]);   sum代表这个节点以下的全部节点总数, 去掉一个节点的联通块的最大的节点数 等于 整个树里的节点数减去这个节点下的总数 和 子树的数目的

最大值。

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <vector>
#define LL __int64
const int maxn = +;
const int INF = <<;
using namespace std;
int head[maxn], vis[maxn], t, d[maxn];
int mi, n;
struct node
{
int u, v, ne;
}e[*maxn]; void add(int u, int v)
{
e[t].u = u;
e[t].v = v;
e[t].ne = head[u];
head[u] = t++;
}
int dfs(int son, int fa)
{
int i, tmp, sum = , x; //sum是以son为根节点的子树的全部的节点数
for(i = head[son]; i != -; i = e[i].ne)
{
tmp = e[i].v;
if(tmp == fa) continue; //避免回去。
x = dfs(tmp, son);
sum += x;
d[son] = max(d[son], x);
}
d[son] = max(d[son], n-sum);
if(d[son]<mi)
mi = d[son];
return sum;
}
int main()
{
int i, f;
while(~scanf("%d", &n))
{
memset(e, , sizeof(e));
memset(head, -, sizeof(head));
memset(vis, , sizeof(vis));
memset(d, , sizeof(d));
t = ;
mi = INF; for(i = ; i < n; i++)
{
int u, v;
scanf("%d%d", &u, &v);
add(u, v);
add(v, u);
}
dfs(, -); //把给的树看成以1为根节点。 f = ;
for(i = ; i <= n; i++)
{
if(d[i]==mi)
{
if(f)
printf(" %d", i);
else
printf("%d", i);
f = ;
}
}
printf("\n");
}
return ;
}

避免回去的时候也可以用vis[]来标记

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <vector>
#define LL __int64
const int maxn = +;
const int INF = <<;
using namespace std;
int head[maxn], vis[maxn], t, d[maxn];
int mi, n;
struct node
{
int u, v, ne;
}e[*maxn]; void add(int u, int v)
{
e[t].u = u;
e[t].v = v;
e[t].ne = head[u];
head[u] = t++;
}
int dfs(int son)
{
int i, tmp, sum = , x;
vis[son] = ;
for(i = head[son]; i != -; i = e[i].ne)
{
tmp = e[i].v;
if(vis[tmp]) continue;
x = dfs(tmp);
sum += x;
d[son] = max(d[son], x);
}
d[son] = max(d[son], n-sum);
if(d[son]<mi)
mi = d[son];
return sum;
}
int main()
{
int i, f;
while(~scanf("%d", &n))
{
memset(e, , sizeof(e));
memset(head, -, sizeof(head));
memset(vis, , sizeof(vis));
memset(d, , sizeof(d));
t = ;
mi = INF; for(i = ; i < n; i++)
{
int u, v;
scanf("%d%d", &u, &v);
add(u, v);
add(v, u);
}
dfs(); f = ;
for(i = ; i <= n; i++)
{
if(d[i]==mi)
{
if(f)
printf(" %d", i);
else
printf("%d", i);
f = ;
}
}
printf("\n");
}
return ;
}

POJ 3107 Godfather (树形dp)的更多相关文章

  1. POJ 3107.Godfather 树形dp

    Godfather Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 7536   Accepted: 2659 Descrip ...

  2. poj 3107 Godfather 求树的重心【树形dp】

    poj 3107 Godfather 和poj 1655差不多,那道会了这个也就差不多了. 题意:从小到大输出树的重心. 题会卡stl,要用邻接表存树..... #include<iostrea ...

  3. POJ.1655 Balancing Act POJ.3107 Godfather(树的重心)

    关于树的重心:百度百科 有关博客:http://blog.csdn.net/acdreamers/article/details/16905653 1.Balancing Act To POJ.165 ...

  4. # [Poj 3107] Godfather 链式前向星+树的重心

    [Poj 3107] Godfather 链式前向星+树的重心 题意 http://poj.org/problem?id=3107 给定一棵树,找到所有重心,升序输出,n<=50000. 链式前 ...

  5. [POJ 1155] TELE (树形dp)

    题目链接:http://poj.org/problem?id=1155 题目大意:电视台要广播电视节目,要经过中转机构,到观众.从电视台到中转商到观众是一个树形结构,经过一条边需要支付成本.现在给你每 ...

  6. Apple Tree POJ - 2486 (树形dp)

    题目链接: D - 树形dp  POJ - 2486 题目大意:一颗树,n个点(1-n),n-1条边,每个点上有一个权值,求从1出发,走V步,最多能遍历到的权值 学习网址:https://blog.c ...

  7. Anniversary party POJ - 2342 (树形DP)

    题目链接:  POJ - 2342 题目大意:给你n个人,然后每个人的重要性,以及两个人之间的附属关系,当上属选择的时候,他的下属不能选择,只要是两个人不互相冲突即可.然后问你以最高领导为起始点的关系 ...

  8. POJ 3342 (树形DP)

    题意 :给出一些上下级关系,要求i和i的直接上级不能同时出现,现在选出一些人构成一个集合,问你这个集合里面的最大人数是都少,同时给出这个最大的人数的集合是否唯一. 思路:树形DP,dp[i][0],表 ...

  9. POJ 2342 (树形DP)

    Anniversary party Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 3863   Accepted: 2172 ...

  10. POJ 1655 Balancing Act&&POJ 3107 Godfather(树的重心)

    树的重心的定义是: 一个点的所有子树中节点数最大的子树节点数最小. 这句话可能说起来比较绕,但是其实想想他的字面意思也就是找到最平衡的那个点. POJ 1655 题目大意: 直接给你一棵树,让你求树的 ...

随机推荐

  1. Shell日期时间和时间戳的转换

    Gitlab的备份文件是以时间戳显示的,类似:1438624820_gitlab_backup.tar 为了更易于阅读,想把文件名转换成日期格式:2015-08-04_gitlab_backup.ta ...

  2. unity3d中dllimport方法的使用,以接入腾讯平台为例!!!

    说到有关dllimport方法可能还有很多人比较陌生,其实我自己也说不太清楚,大概说说什么时候要用它. 事实上功能类似于调用android的第三包,我们想要使用苹果上特定的api或者第三方平台的一些东 ...

  3. java多线程基础知识

    1.ThrTest.java 继承Thread类方式 public class ThrTest extends Thread { private String name; public ThrTest ...

  4. VirtualBox中开启Linux的SSH(CentOS)

    http://my.oschina.net/pangyangyang/blog/177869 第一次干用SSH连接安装在VirtualBox上的Linux的事情,打算买个云空间用用的所以先拿个Cent ...

  5. POJ 2531 Network Saboteur (枚举+剪枝)

    题意:给你一个图,图中点之间会有边权,现在问题是把图分成两部分,使得两部分之间边权之和最大. 目前我所知道的有四种做法: 方法一:状态压缩 #include <iostream> #inc ...

  6. C# 设置程序开机自动运行(+注册表项)

    有时候我们需要让软件安装好了,开机自动运行,这时我们需要把启动项加载到注册表中,需要注意的时现在很多杀毒软件在其他软件更改注册表的时候会有提示,可能会阻止.下面代码包含增加启动项到注册表和删除启动项. ...

  7. 传说中的WCF(6):数据协定(b)

    我们继续,上一回我们了解了数据协定的一部分内容,今天我们接着来做实验.好的,实验之前先说一句:实验有风险,写代码须谨慎. 实验开始!现在,我们定义两个带数据协定的类——Student和AddrInfo ...

  8. OpenThreadToken,OpenProcessToken DuplicateToken 取得句柄的令牌

    https://msdn.microsoft.com/en-us/library/windows/desktop/aa379296(v=vs.85).aspx https://msdn.microso ...

  9. [iOS]利用通知实现监听系统键盘

    // // ViewController.m // text // // Created by 李东旭 on 16/1/22. // Copyright © 2016年 李东旭. All rights ...

  10. list、set、map的特点

    java 集合(list.set.map)的特点 集合相关的类有一大堆,一般也只用到常用的方法增删改查,而且它它们的方法名也基本一样,所以一直都不知道什么时候用什么集合, 今天趁有空特意从网上整理资料 ...