正题
题目链接:https://ac.nowcoder.com/acm/contest/1111/J
题目大意
一棵树,每个点有一个威力值,每次破坏一个点会受到与它相连没有破坏的点的威力值之和的伤害。求破坏所有点的最小伤害。
解题思路
因为是一棵树,所有我们可以看为每条边两边的点选择一个先破坏,显然先破坏威力值高的点,因为没有环,所有这些边之间的选择不会相互影响,所以先从威力值大的破坏到小的即可。
codecodecode
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=1e5+100;
struct node{int to,next;
}a[N*2];
int n,p[N],num[N],ls[N],ans,tot;
bool v[N];
void addl(int x,int y)
{a[++tot].to=y;a[tot].next=ls[x];ls[x]=tot;
}
bool cmp(int x,int y)
{return p[x]>p[y];}
int main()
{scanf("%d",&n);for(int i=1;i<=n;i++)scanf("%d",&p[i]),num[i]=i;for(int i=1;i<n;i++){int x,y;scanf("%d%d",&x,&y);addl(x,y);addl(y,x);}sort(num+1,num+1+n,cmp);for(int i=1;i<=n;i++){int x=num[i];for(int j=ls[x];j;j=a[j].next)if(!v[a[j].to]) ans+=p[a[j].to];v[x]=1;}printf("%d",ans);
}