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]
两者比较取最大就可以了
POJ 3107
求解问题的思想是和上面的题目是基本相同的,除了输入输出方式需要改变,然后数组开大点就可以照抄上面代码了
根据题目的图很好理解意思,就是记录每一个点的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; }
相关文章推荐
- POJ 1655 Balancing Act&&POJ 3107 Godfather(树的重心)
- poj&nbsp;1655&nbsp;balancing&nbsp;act&nbsp;dfs
- POJ 1655 Balancing Act
- POJ 1655 Balancing Act 树形DP入门题
- POJ-1655 Balancing Act 树的重心
- POJ 1655 Balancing Act【树形DP】POJ 1655 Balancing Act Balancing Act POJ 1655
- poj 1655 Balancing Act(树形DP)
- POJ 1655 Balancing Act 树形DP入门题
- poj1655 Balancing Act 【树形DP(很弱)】
- poj - 1655 Balancing Act
- POJ 1655 Balancing Act(简单树状DP)
- POJ 1655 - Balancing Act 树型DP
- POJ 1655 Balancing Act (dfs)
- poj 1655 Balancing Act(树dp)
- poj 1655 Balancing Act(求树的重心)
- POJ--1655--Balancing Act--简单树形DP
- POJ1655 Balancing Act——树的重心,Dfs
- poj 1655 Balancing Act(树形dp)
- poj 1655 Balancing Act
- POJ 1655 - Balancing Act 树形DP