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 }
View Code

 

posted @ 2018-08-06 10:41  KingSann  阅读(95)  评论(0编辑  收藏  举报