51nod 1737配对

题意:给定一个n个点的带边权树,  保证n是偶数,给这个树两两配对,使得配对后的点路径和最大,输出最大值。

其实是个很简单的题,但还是被绊了。这充分说明现在连简单题都做不来了555

单独考虑每条边。每个点对答案的贡献就是它被使用的次数乘以权值,而每条边的系数其实是互不影响的,而系数最大值就是它两端的点个数的min,把这个算出来加起来就完了。

为什么这样是对的,即为什么每个系数互不影响,因为完全可以构建一个以重心为中心的菊花图,那样构建完全可以满足每个点系数最大化。

感觉这个思维方式硬伤啊。。多做点题吧。。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define N 100005
 4 #define LL long long
 5 inline int read(){
 6     int x=0,f=1; char a=getchar();
 7     while(a<'0' || a>'9') {if(a=='-') f=-1; a=getchar();}
 8     while(a>='0' && a<='9') x=x*10+a-'0',a=getchar();
 9     return x*f;
10 }
11 struct edges{
12     int to,v,next;
13 }e[2*N];
14 int n,head[N],cnt=1,son[N];
15 LL ans;
16 inline void insert(){
17     int u=read(),v=read(),c=read();
18     e[++cnt]=(edges){v,c,head[u]};head[u]=cnt;
19     e[++cnt]=(edges){u,c,head[v]};head[v]=cnt;
20 }
21 void dfs(int x,int fa){
22     son[x]=1;
23     for(int i=head[x];i;i=e[i].next){
24         if(e[i].to==fa) continue;
25         dfs(e[i].to,x); son[x]+=son[e[i].to];
26         ans+=(LL)min(son[e[i].to],n-son[e[i].to])*e[i].v;
27     }
28 }
29 int main(){
30     n=read();
31     for(int i=1;i<n;i++) insert();
32     dfs(1,0);
33     printf("%lld
",ans);
34     return 0;
35 }
原文地址:https://www.cnblogs.com/enigma-aw/p/6275197.html