D. Sum in the tree(树形+贪心)

题目链接;http://codeforces.com/contest/1099/problem/D

题目大意:给出一棵树,每个节点到根节点的路径上经过的所有点的权值之和,其深度为偶数的节点的信息全部擦除了,也就是用-1表示,让你求最终所有点权之和(要求最小)

具体思路:对于每一个节点,这个点到根节点的权值最小的时候是他的所有的根节点的最小值,然后一路更新上去就可以了,最后求值得时候,我们求父亲节点和子节点之间的差就可以了, 如果差值为负值就是非法情况。

AC代码:

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 # define ll long long
  4 # define inf 0x3f3f3f3f
  5 const int maxn = 1e5+100;
  6 const int mod = 1e9+7;
  7 int head[maxn],num,dp[maxn][3],flag=1,vis[maxn];
  8 struct node
  9 {
 10     int nex;
 11     int to;
 12 } edge[maxn*2];
 13 ll sum;
 14 void addedge(int fr,int to)
 15 {
 16     edge[num].to=to;
 17     edge[num].nex=head[fr];
 18     head[fr]=num++;
 19 }
 20 void dfs1(int fr,int rt)
 21 {
 22     if(dp[fr][0]==-1)
 23     {
 24         int minn=inf;
 25         for(int i=head[fr]; i!=-1; i=edge[i].nex)
 26         {
 27             int to=edge[i].to;
 28             if(to==rt)
 29                 continue;
 30             minn=min(minn,dp[to][0]);
 31         }
 32         dp[fr][0]=minn;
 33         //cout<<fr<<" "<<dp[fr][0]<<endl;
 34     }
 35     for(int i=head[fr]; i!=-1; i=edge[i].nex)
 36     {
 37         int to=edge[i].to;
 38         if(to==rt)
 39             continue;
 40         dfs1(to,fr);
 41         if(dp[to][0]==inf)
 42             dp[to][0]=dp[fr][0];
 43     }
 44 }
 45 void dfs2(int fr,int rt)
 46 {
 47     if(flag==0)
 48         return ;
 49     for(int i=head[fr]; i!=-1; i=edge[i].nex)
 50     {
 51         int to=edge[i].to;
 52         if(to==rt)
 53             continue;
 54             dfs2(to,fr);
 55         sum+=(dp[to][0]-dp[fr][0]);
 56         if(dp[to][0]-dp[fr][0]<0)
 57         {
 58             flag=0;
 59         }
 60 
 61     }
 62 }
 63 
 64 int main()
 65 {
 66     int n;
 67     scanf("%d",&n);
 68     for(int i=1; i<=n; i++)
 69     {
 70         head[i]=-1;
 71     }
 72     int tmp;
 73     for(int i=2; i<=n; i++)
 74     {
 75         scanf("%d",&tmp);
 76         addedge(tmp,i);
 77         addedge(i,tmp);
 78     }
 79     for(int i=1; i<=n; i++)
 80     {
 81         scanf("%d",&dp[i][0]);
 82     }
 83     dfs1(1,-1);
 84     dfs2(1,-1);
 85     sum+=dp[1][0];
 86     for(int i=1; i<=n; i++)
 87     {
 88      //   cout<<dp[i][0]<<endl;
 89     }
 90 //        for(int i=n-1; i>=1; i--)
 91 //        {
 92 //            sum+=(dp[i+1][0]-dp[i][0]);
 93 //            if(dp[i+1][0]-dp[i][0]<0)flag=0;
 94 //        }
 95     if(flag==0)
 96         sum=-1;
 97     printf("%lld\n",sum);
 98     return 0;
 99 }
100 /*
101 5
102 1 2 2 3
103 1 -1 2 3 -1
104 3
105 */
106  

 

posted @ 2019-01-07 22:25  Let_Life_Stop  阅读(298)  评论(0编辑  收藏  举报