cogs 1143. [石門中學2009] 切割樹
阿新 • • 發佈:2017-09-09
wid pan ipa one ring table div sub ++
1143. [石門中學2009] 切割樹
★ 輸入文件:treecut.in
輸出文件:treecut.out
簡單對比
時間限制:1 s 內存限制:128 MB
treecut
題目描述:
有一個N個節點的無根樹,各節點編號為1..N,現在要求你刪除其中的一個點,使分割開的連通塊中節點個數都不超過原來的一半多。
數據範圍
1 <= N <= 10,000
輸入文件 treecut.in
第一行:一個整數N。
後面有N-1行:每行兩個整數 X 和 Y,表示一個邊連接的兩個節點號。
輸出文件 treecut.out
輸出所有可能選擇的點。如果有多個節點,按編號從小到大輸出,每個一行。 如果找不到這樣的點,輸出一行:"NONE".
樣例
輸入 |
10 |
樣例說明: 刪除3號或8號 節點,則分枝 最多有5個節點
|
輸出 |
3 |
|
思路:dfs一邊,然後枚舉每個點作為切割點。
#include<vector> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #defineMAXN 10001 using namespace std; vector<int>vec[MAXN]; int n,S,tot; int dad[MAXN],size[MAXN]; void dfs(int now){ size[now]=1; for(int i=0;i<vec[now].size();i++) if(dad[now]!=vec[now][i]){ dad[vec[now][i]]=now; dfs(vec[now][i]); size[now]+=size[vec[now][i]]; } } bool judge(int now){ if(size[1]-size[now]>S) return false; for(int i=0;i<vec[now].size();i++) if(dad[now]!=vec[now][i]){ int to=vec[now][i]; if(size[to]>S) return false; } return true; } int main(){ freopen("treecut.in","r",stdin); freopen("treecut.out","w",stdout); scanf("%d",&n); S=n/2; for(int i=1;i<n;i++){ int u,v; scanf("%d%d",&u,&v); vec[u].push_back(v); vec[v].push_back(u); } dfs(1); for(int i=1;i<=n;i++) if(judge(i)) cout<<i<<endl; }
cogs 1143. [石門中學2009] 切割樹