[BZOJ3391][Usaco2004 Dec]Tree Cutting网络破坏
Description
约翰意识到贝茜建设网络花费了他巨额的经费,就把她解雇了.贝茜很愤怒,打算狠狠报
复.她打算破坏刚建成的约翰的网络. 约翰的网络是树形的,连接着N(1≤N≤10000)个牛棚.她打算切断某一个牛棚的电源,使和这个牛棚相连的所有电缆全部中断.之后,就会存在若干子网络.为保证破坏够大,每一个子网的牛棚数不得超过总牛棚数的一半,那哪些牛棚值得破坏呢?
Input
第1行:一个整数N.
第2到N+1行:每行输入两个整数,表示一条电缆的两个端点.
Output
按从小到大的顺序,输出所有值得破坏的牛棚.如果没有一个值得破坏,就输出“NONE”.
Sample Input
10
1 2
2 3
3 4
4 5
6 7
7 8
8 9
9 10
3 8
1 2
2 3
3 4
4 5
6 7
7 8
8 9
9 10
3 8
Sample Output
3
8
如果牛棚3或牛棚8被破坏,剩下的三个子网节点数将是5,2,2,没有超过5的.
如果是树的话比较好处理...
直接dfs找就行了。
如果不是树...
不会233
// By BriMon #include <iostream> #include <cstring> #include <cstdio> #include <vector> #include <algorithm> #include <queue> using namespace std; inline int read(){ int res=0;char ch=getchar(); while(!isdigit(ch)) ch=getchar(); while(isdigit(ch)){res=(res<<3)+(res<<1)+(ch^48);ch=getchar();} return res; } #define N 10005 int n; struct edge{ int nxt, to; }ed[N*2]; int head[N], cnt; inline void add(int x, int y) { ed[++cnt] = (edge){head[x], y}; head[x] = cnt; } bool ok[N]; int siz[N]; void dfs(int x, int fa) { siz[x] = 1; for (int i = head[x] ; i ; i = ed[i].nxt) { int to = ed[i].to; if (fa != to) { dfs(to, x); siz[x] += siz[to]; if (siz[to] > n / 2) ok[x] = false; } } if (n - siz[x] > n / 2) ok[x] = false; } int main() { n = read(); for (int i = 1 ; i < n ; i ++) { int x = read(), y = read(); add(x, y), add(y, x); } for (int i = 1 ; i <= n ; i ++) ok[i] = true; dfs(1, 0); bool flag = 0; for (int x = 1 ; x <= n ; x ++) if (ok[x]) printf("%d\n", x), flag = 1; if (!flag) puts("NONE"); return 0; }