Tree Cutting POJ - 2378(树形DP)
題意:有n個谷倉有n-1條路連接,問最少刪除哪幾個點才能使得刪除點后得到的連通圖的加點數不大于n/2.
分析:求樹的重心的變形題,poj3107的簡單版,一遍dfs從葉子到根轉移找出找到以每個節點為根的子樹的結點數,f[u]={ f[v1]+f[v2]+.....+f[vn] }+1;使得每棵子樹節點數小于n/2,并且父節點得那個連通圖節點數小于等于n/2,即n-f[u]<=n/2.
如果沒有這樣的點,輸出NONE
Time limit? ? ?1000 ms
Memory limit? ? ?65536 kB
OS? ? ?Linux
Source? ? ??USACO 2004 December Silver
After Farmer John realized that Bessie had installed a "tree-shaped" network among his N (1 <= N <= 10,000) barns at an incredible cost, he sued Bessie to mitigate his losses.?
Bessie, feeling vindictive, decided to sabotage Farmer John's network by cutting power to one of the barns (thereby disrupting all the connections involving that barn). When Bessie does this, it breaks the network into smaller pieces, each of which retains full connectivity within itself. In order to be as disruptive as possible, Bessie wants to make sure that each of these pieces connects together no more than half the barns on FJ.?
Please help Bessie determine all of the barns that would be suitable to disconnect.
Input
* Line 1: A single integer, N. The barns are numbered 1..N.?
* Lines 2..N: Each line contains two integers X and Y and represents a connection between barns X and Y.
Output
* Lines 1..?: Each line contains a single integer, the number (from 1..N) of a barn whose removal splits the network into pieces each having at most half the original number of barns. Output the barns in increasing numerical order. If there are no suitable barns, the output should be a single line containing the word "NONE".
Sample Input
10 1 2 2 3 3 4 4 5 6 7 7 8 8 9 9 10 3 8Sample Output
3 8Hint
INPUT DETAILS:?
The set of connections in the input describes a "tree": it connects all the barns together and contains no cycles.?
OUTPUT DETAILS:?
If barn 3 or barn 8 is removed, then the remaining network will have one piece consisting of 5 barns and two pieces containing 2 barns. If any other barn is removed then at least one of the remaining pieces has size at least 6 (which is more than half of the original number of barns, 5).
題意:
給定一棵無向樹,節點為n(n<=10000),問刪除那些節點可以使得新圖中的每一個連通分支的節點數都不超過小于n/2
思路:
樹形dp,任意定跟,求出每個節點的兒子節點,每個點為根的子樹的節點數dp[i],然后考察每一個點,如果n-dp[i]<=n/2,以及以i的每一個兒子為根的子樹的節點數都dp[u]<=n/2,那么這個點就滿足條件
/*題意:給了一棵節點數為n的樹的對應關系,讓判斷去掉哪些 節點能使子數的大小小于等于n/2,并將符合條件的節點從小到 大輸出,如果沒有符合條件的節點,則輸出 “NONE”。 思路:既然是讓求哪些ji節點符合條件,可以用鄰接表構建一個 圖,然后用dfs找出每一個節點下連的圖的da'x大小些節點符合 條件,將節點存入ans數組中。*/ #include<cstdio> #include<cstring> #include<algorithm> #define N 10010 using namespace std; int n,s,e,first[N],book[N],ans[N]; struct node {int x,y; }que[2*N]; void add(int x,int y) //構建鄰接表的函數 {que[e].x=x;que[e].y=first[y];first[y]=e++; } int dfs(int x) {int num=0,sum=0;book[x]=1;int k=first[x],flag=0;while(k!=-1){if(!book[que[k].x]){num=dfs(que[k].x);sum+=num;if(num>n/2) //x節點下的圖的大小超過了n/2,不符合條件flag=1;}k=que[k].y;}if(n-sum-1>n/2) //另一半是否小于等于n/2flag=1;if(!flag)ans[s++]=x;return sum+1; //加上自己 } int main() {while(~scanf("%d",&n)){memset(first,-1,sizeof(first));//初始化memset(book,0,sizeof(book));s=e=0; //有s個節點符合條件,e用鄰接表表示無向圖的大小int a,b;for(int i=1;i<n;i++){scanf("%d%d",&a,&b);add(a,b); //構建鄰接表add(b,a); //無向圖}a=dfs(1); //從第一個點開始嘗試if(s) //有s個節點符合條件{sort(ans,ans+s); //從小到大排序,輸出for(int i=0;i<s;i++)printf("%d\n",ans[i]);}else //沒有符合條件的節點printf("NONE\n");} }?
總結
以上是生活随笔為你收集整理的Tree Cutting POJ - 2378(树形DP)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 脸部刮痧几天刮一次效果更好
- 下一篇: 针灸丰胸有效果吗