luogu P1268 树的重量

嘟嘟嘟

 

一道非常好的构造题。

我反正是一点思路都没有,最后还是看了题解。

假如n = 2,那么树的重量就是di,j

然后n = 3,画一个图:,则重量=(d1,3 + d2,3 - d1,2) / 2。

n = 4同理:,加上的应该是(d1,4 + dj,4 - d1,j) / 2 (j < 4)的最小值,这里面j = 3。因为如果不是最小值的话,比如 j = 2,那么多加了一段图中红色的部分。

依次类推,树的重量就构造出来了。

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cmath>
 4 #include<algorithm>
 5 #include<cstring>
 6 #include<cstdlib>
 7 #include<cctype>
 8 #include<vector>
 9 #include<stack>
10 #include<queue>
11 using namespace std;
12 #define enter puts("") 
13 #define space putchar(' ')
14 #define Mem(a, x) memset(a, x, sizeof(a))
15 #define rg register
16 typedef long long ll;
17 typedef double db;
18 const int INF = 0x3f3f3f3f;
19 const db eps = 1e-8;
20 const int maxn = 35;
21 inline ll read()
22 {
23   ll ans = 0;
24   char ch = getchar(), last = ' ';
25   while(!isdigit(ch)) last = ch, ch = getchar();
26   while(isdigit(ch)) ans = (ans << 1) + (ans << 3) + ch - '0', ch = getchar();
27   if(last == '-') ans = -ans;
28   return ans;
29 }
30 inline void write(ll x)
31 {
32   if(x < 0) x = -x, putchar('-');
33   if(x >= 10) write(x / 10);
34   putchar(x % 10 + '0');
35 }
36 
37 int n, G[maxn][maxn];
38 
39 int main()
40 {
41   while(scanf("%d", &n) && n)
42     {
43       Mem(G, 0);
44       for(int i = 1; i <= n; ++i)
45     for(int j = i + 1; j <= n; ++j) G[i][j] = G[j][i] = read();
46       int ans = 0;
47       for(int i = 2; i <= n; ++i)
48     {
49       int Min = INF;
50       for(int j = 1; j < i; ++j) Min = min(Min, (G[1][i] + G[j][i] - G[1][j]) >> 1);
51       ans += Min;
52     }
53       write(ans), enter;
54     }
55   return 0;
56 }
View Code

 

posted @ 2018-10-31 13:23  mrclr  阅读(392)  评论(0编辑  收藏  举报