C++——NOIP模拟题——tree

来源:互联网 发布:vb宽度高度 编辑:程序博客网 时间:2024/06/14 22:06
【题目大意】 
  给出一个树,每个结点 i都有一个权值W[i]。现在要求你选出一些点,满足任意两个
点之间都不能够有边相连,并且使得选出的点的总权值最大。 
【输入数据】 
  第一行一个数 N表示结点数目 
  接下来一行N个数分别表示结点 1~N 的权值。 
  接下来 N-1行每行两个数表示一条边 
【输出数据】 
  一个数表示最大的总权值 
【Sample Input】 

10 8 
1 2 
 
【Sample Output】 
10 
【数据规模】 
30%:N<=10 

100%:N<=10,0000,|W[i]|<=10^9 

#include<iostream>#include<cstdio>using namespace std;int n,tot;int w[100001],first[100001],next[200001],en[200001];long long g[100001],f[100001];bool v[100001];inline int readint(){    int i=0,f=1;    char ch;    for(ch=getchar();ch<'0'||ch>'9';ch=getchar());    for(;ch>='0' && ch<='9';ch=getchar())        i=(i<<3)+(i<<1)+ch-'0';    return i*f;}inline void add(int u,int v){next[++tot]=first[u];first[u]=tot;en[tot]=v;}inline void dfs(int x){v[x]=1;g[x]=0;f[x]=w[x];for(int k=first[x],i;k;k=next[k])if(!v[i=en[k]]){dfs(i);g[x]+=max(f[i],g[i]);f[x]+=g[i];}}int main(){freopen("tree.in","r",stdin);freopen("tree.out","w",stdout);n=readint();for(int i=1;i<=n;++i) scanf("%d",w+i);int u,v;for(int i=1;i<n;++i){u=readint();v=readint();add(u,v);add(v,u);}dfs(1);cout<<max(g[1],f[1]);return 0;}


0 0
原创粉丝点击