JZOJ 4625. 【NOIP2016提高A组模拟7.15】树
数据范围很小也许是装压……但并不知道怎么装压……
有一个有趣的骗分方法:将度数从大到小排序,每次取度数最大的并连边,加上特判无解的情况一共有40pts
题解是这样的:
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int N = 25; 4 5 queue<pair<int, int> > q; 6 int n, a[N], cnt; 7 vector<int> G[N]; 8 int mx[N], ans[N]; 9 10 namespace xuanxuepianfen { 11 void dfs(int u) { 12 // cout << u << "{"; 13 ans[u] = mx[u] = 0; 14 for(int i = 0 ; i < G[u].size() ; ++ i) { 15 int v = G[u][i]; 16 dfs(v); 17 ans[u] = max(ans[u], max(ans[v], mx[u] + mx[v] + 1)); 18 mx[u] = max(mx[u], mx[v] + 1); 19 20 } 21 ans[u] = max(ans[u], mx[u]); 22 // cout << "}"; 23 } 24 void sol() { 25 sort(a + 1, a + 1 + n, greater<int>()); 26 for(int i = 1 ; i <= n ; ++ i) { 27 ++ cnt; 28 if(q.empty()) { 29 q.push(make_pair(cnt, a[i])); 30 } else { 31 while(q.front().second == 0) q.pop(); 32 q.front().second --; 33 G[q.front().first].push_back(cnt); 34 q.push(make_pair(cnt, a[i] - 1)); 35 } 36 } 37 dfs(1); 38 printf("%d\n", ans[1]); 39 } 40 } 41 int main() { 42 scanf("%d", &n); 43 int sum = 0; 44 for(int i = 1 ; i <= n ; ++ i) scanf("%d", &a[i]), sum += a[i]; 45 if(sum != 2 * (n - 1)) return puts("-1"), 0; 46 int ans = n - 1; 47 for(int i = 1 ; i <= n ; ++ i) ans -= max(2, a[i]) - 2; 48 printf("%d\n", ans); 49 }