Luogu 1351(树形dp)

来源:互联网 发布:上海知楚王琦 编辑:程序博客网 时间:2024/06/13 00:55

传送门
NOIP 2014 D1T2(“树形dp”)
其实根本算不上什么dp,就是乱搞。
对于x点,用于它直接相连的点来更新答案(记录最大值、次大值、权值和)即可。
注意:long long!!!数据范围什么的都是假的,要看答案会不会爆int。。。60分了半天。。。

#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#include<vector>using namespace std;typedef long long ll;const int MAXN=2e5+2;const int MOD=10007;int n,m;int head[MAXN],edge=0;struct EDGE {    int v,nxt;}e[MAXN<<1];int val[MAXN],ssum[MAXN],ans=0;int fir[MAXN],sec[MAXN],mx=0;inline int read() {    int x=0;char c=getchar();    while (c<'0'||c>'9') c=getchar();    while (c>='0'&&c<='9') x=x*10+c-'0',c=getchar();    return x;}inline void adde(int u,int v) {    e[edge].nxt=head[u],e[edge].v=v,head[u]=edge++;    e[edge].nxt=head[v],e[edge].v=u,head[v]=edge++;}void dfs1(int p,int fa) {    ssum[p]=0,fir[p]=0,sec[p]=0;    if (fa) fir[p]=val[fa],ssum[p]+=val[fa];    for (int i=head[p];~i;i=e[i].nxt) {        int v=e[i].v;        if (v==fa) continue;        ssum[p]+=val[v];        if (val[v]>=fir[p]) sec[p]=fir[p],fir[p]=val[v];        else if (val[v]<fir[p]&&val[v]>sec[p]) sec[p]=val[v];        dfs1(v,p);    }    mx=max(mx,fir[p]*sec[p]);}void dfs2(int p,int fa) {    for (int i=head[p];~i;i=e[i].nxt) {        int v=e[i].v;        ans=(ans+2ll*val[v]*((ssum[p]-=val[v])))%MOD;        if (v^fa) dfs2(v,p);    }}int main() {//  freopen("P1351.in","r",stdin);    memset(head,-1,sizeof(head));    n=read();    for (register int i=1;i<n;++i) {        int u=read(),v=read();        adde(u,v);    }    for (register int i=1;i<=n;++i) val[i]=read();    dfs1(1,0);    dfs2(1,0);//  for (int i=1;i<=n;++i)//      printf("%d %d\n",sec[i],fir[i]);    printf("%d %d\n",mx,ans);    return 0;//8 1 2 2 4 1 3 3 5 3 6 3 7 5 8 3 2 6 3 1 5 9 4}
原创粉丝点击