USACO 2004 DEC网络破坏Tree Cutting(DFS)
Posted gzh01
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了USACO 2004 DEC网络破坏Tree Cutting(DFS)相关的知识,希望对你有一定的参考价值。
题目描述
约翰意识到贝茜建设网络花费了他巨额的经费,就把她解雇了.贝茜很愤怒,打算狠狠报
复.她打算破坏刚建成的约翰的网络.
约翰的网络是树形的,连接着N(1≤N≤10000)个牛棚.她打算切断某一个牛棚的电源,使和这个牛棚相连的所有电缆全部中断.之后,就会存在若干子网络.为保证破坏够大,每一个子网的牛棚数不得超过总牛棚数的一半,哪些牛棚值得破坏呢?
输入
第1行:一个整数N.
第2到N行:每行输入两个整数,表示一条电缆的两个端点.
输出
按从小到大的顺序,输出所有值得破坏的牛棚.如果没有一个值得破坏,就输出“NONE”.
本题网络是一个无根树,那么我们可以进行搜索,记录每一棵以x节点为根的子树的节点数,最后枚举每一个点,假如这个点以它的子节点为根的子树节点数,与节点总数减去这个点为根的子树节点数均不大于n/2,就可以将这个点输出。(其实这道题根本不可能有NONE的情况)
1 #include <cstdio> 2 #include <vector> 3 4 #define N 10001 5 6 int n,a,b,ans,num[N],pre[N]; 7 std::vector<int> g[N]; 8 9 int dfs(int u,int fa){ 10 pre[u]=fa; 11 if((g[u].size()==1)&&(u!=1))return num[u]=1; 12 int sum=0; 13 for(int i=0;i<g[u].size();++i){ 14 int v=g[u][i]; 15 if(v==fa)continue; 16 sum+=dfs(v,u); 17 } 18 return num[u]=sum+1; 19 } 20 21 int main(void){ 22 scanf("%d",&n); 23 for(int i=1;i<n;++i){ 24 scanf("%d%d",&a,&b); 25 g[a].push_back(b); 26 g[b].push_back(a); 27 } 28 dfs(1,0); 29 for(int i=1;i<=n;++i){ 30 bool p=true; 31 if(num[1]-num[i]>n/2)continue; 32 for(int j=0;j<g[i].size();++j){ 33 int v=g[i][j]; 34 if(v==pre[i])continue; 35 if(num[v]>n/2)p=false; 36 } 37 if(p){ 38 ++ans; 39 printf("%d ",i); 40 } 41 } 42 if(ans==0)printf("NONE"); 43 }
以上是关于USACO 2004 DEC网络破坏Tree Cutting(DFS)的主要内容,如果未能解决你的问题,请参考以下文章
BZOJ 3391 [Usaco2004 Dec]Tree Cutting网络破坏:dfs无根树 节点分枝子树大小
BZOJ 3390 Usaco2004 Dec Bad Cowstractors 牛的报复
Bzoj 3389: [Usaco2004 Dec]Cleaning Shifts安排值班 最短路,神题
bzoj 3389: [Usaco2004 Dec]Cleaning Shifts安排值班 -- 贪心