NOIP2014联合权值

发现去年简直弱爆了,这么简单的一眼题都傻逼逼的不会做,NOIP快来了回去做一下这些简单题,然而边忘记开2倍N了然后70分无语了好久还以为是dfs栈爆了去写了bfs,算了算了

DFS:

#include<cstdio>
#include<iostream>
#include<algorithm>
#define N 200005
#define inf 10007
#define LL long long
using namespace std;
struct edge
{
       int x,y,next;
}e[N*2];
LL w[N],sum[N],ls[N],cnt,faf[N],ma[N];
LL ans,anss;
int n;

void add(int x,int y)
{
     int t=++cnt;e[t].x=x;e[t].y=y;e[t].next=ls[x];ls[x]=t;
     t=++cnt;e[t].x=y;e[t].y=x;e[t].next=ls[y];ls[y]=t;
     }

void dfs(int x,int pre,int prep)
{
     if (prep>0) faf[x]=prep;
     sum[pre]+=w[x];
     if (!ma[pre]) ma[pre]=x;
     if (w[x]>w[ma[pre]]) ma[pre]=x;
     for (int i=ls[x];i!=0;i=e[i].next)
     {
         if (e[i].y!=pre) dfs(e[i].y,x,pre);
         }
     }
     
void work(int x,int pre)         
{
//     cout<<anss<<' '<<ans<<endl;
     ans=(ans+w[faf[x]]*w[x]*2)%inf;
     anss=max(anss,w[faf[x]]*w[x]);
     ans=(ans+(sum[pre]-w[x])*w[x])%inf;
     if (ma[pre]!=x) anss=max(anss,w[ma[pre]]*w[x]);
//     cout<<anss<<' '<<ans<<endl;
     for (int i=ls[x];i!=0;i=e[i].next)
     {
         if (e[i].y!=pre) work(e[i].y,x);
         }
     }

int main()
{
    freopen("link.in","r",stdin);
    freopen("link.out","w",stdout);
    scanf("%d",&n);
    for (int i=1;i<n;i++)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        add(x,y);
        }
    for (int i=1;i<=n;i++) scanf("%d",&w[i]);
    dfs(1,0,-1);
    work(1,0);
    printf("%lld %lld\n",anss,ans);
    return 0;
}
然后是BFS:

#include<cstdio>
#include<iostream>
#include<algorithm>
#define N 200005
#define inf 10007
#define LL long long
using namespace std;
struct edge
{
       int x,y,next;
}e[N*2];
LL w[N],sum[N],ls[N],cnt,faf[N],ma[N];
LL ans,anss;
int n;

void add(LL x,LL y)
{
     int t=++cnt;e[t].x=x;e[t].y=y;e[t].next=ls[x];ls[x]=t;
     t=++cnt;e[t].x=y;e[t].y=x;e[t].next=ls[y];ls[y]=t;
     }

int q[N],pre[N],prep[N],h,t,v[N];
void bfs()
{
     h=0;t=1;q[t]=1;pre[t]=0;prep[t]=-1;memset(v,0,sizeof(v));v[1]=1;
     while (h<t)
     {
           h++;
           if (prep[h]>0) faf[q[h]]=prep[h];
           sum[pre[h]]+=w[q[h]];
           if (!ma[pre[h]]) ma[pre[h]]=q[h];
           if (w[q[h]]>w[ma[pre[h]]]) ma[pre[h]]=q[h];
           for (int i=ls[q[h]];i!=0;i=e[i].next)
           {
               if (!v[e[i].y]) 
               {
                               q[++t]=e[i].y;
                               pre[t]=q[h];
                               prep[t]=pre[h];
                               v[e[i].y]=1;
                               }
               }
           }
     }
     
void work()
{
     h=0;t=1;q[t]=1;pre[t]=0;memset(v,0,sizeof(v));v[1]=1;
     while (h<t)
     {
           h++;int x=q[h];
           ans=(ans+(w[faf[x]]*w[x]%inf)*2)%inf;
           anss=max(anss,w[faf[x]]*w[x]);
//           cout<<anss<<' '<<ans<<' '<<x<<' '<<faf[x]<<' '<<pre[h]<<' '<<w[faf[x]]<<' '<<w[x]<<endl;
           ans=(ans+(sum[pre[h]]-w[x])%inf*w[x])%inf;
           if (ma[pre[h]]!=x) anss=max(anss,w[ma[pre[h]]]*w[x]);
//           cout<<anss<<' '<<ans<<' '<<x<<' '<<faf[x]<<' '<<pre[h]<<' '<<ma[pre[h]]<<endl;
           for (int i=ls[q[h]];i!=0;i=e[i].next)
           {
               if (!v[e[i].y]) 
               {
                               q[++t]=e[i].y;
                               pre[t]=q[h];
                               v[e[i].y]=1;
                               }
               }
           }
     }     

int main()
{
    freopen("link.in","r",stdin);
    freopen("link.out","w",stdout);
    scanf("%d",&n);
    for (int i=1;i<n;i++)
    {
        LL x,y;
        scanf("%lld %lld",&x,&y);
        add(x,y);
        }
    for (int i=1;i<=n;i++) scanf("%lld",&w[i]);
    bfs();
    work();
    printf("%lld %lld\n",anss,ans);
    return 0;
}



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值