codevs3728 联合权值

Posted ACforever

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了codevs3728 联合权值相关的知识,希望对你有一定的参考价值。

题目描述 Description

技术分享

输入描述 Input Description

技术分享

输出描述 Output Description

技术分享

样例输入 Sample Input

技术分享

样例输出 Sample Output

技术分享

技术分享

数据范围及提示 Data Size & Hint

技术分享

思路:
1、以每一个点为轴,左右两个点算权值
2、注意加法结合律(a+b+c)2 = a2 + b2 + c2 + 2ab + 2ac + 2bc
3、取模问题,(a+b)%c ≠ (a%c + b%c)%c,(a + b) % c = (a + b%c)%c
代码:
(注意链式前向星的使用)
#include<cstdio>
#include<iostream>
using namespace std;
const int maxn =400020;
struct edge{
    int next;
    int to;
    int power;
};
edge test[maxn];
int head[maxn],cur = 0,n,j[maxn],p[maxn],max1[maxn],max2[maxn],nmax1[maxn],coun[maxn];
long long int vall = 0,vmax = 0,sub =0;

int use(int i)
 {   
     int t=head[i];
     int ti,tmp,sum=0,cha2=0;
     
     while (t!=-1)
     {    ti=test[t].to;
          sum=(sum+p[ti]%10007)%10007;
          cha2+=p[ti]*p[ti]%10007;
          if (p[ti]>max1[i] )
           { max1[i]=p[ti];
             nmax1[i]=ti;
           }
           t=test[t].next;
           coun[i]++;
          
     }
    sum=(sum*sum%10007 +10007-cha2%10007)%10007;
    vall+=sum%10007;
    return sum;
 } 

/*int dfs(int deep,int last,int now){
    if(deep == 2){
        if(last == now) return 0;
        int temp;
        temp =  p[now]* p[last];
        if(temp > vmax) vmax = temp;
        return 0;
    }

    for(int k=head[now];k>-1;k=test[k].next){
        dfs(deep + 1,last,test[k].to);
    }
} */
void dfs(int i)
 {  int ansi=1;
    if (coun[i]>1)
     {
        int t=head[i];
        int ti;
        while (t!=-1)
         {
          ti=test[t].to;         
           if (ti!=nmax1[i] )
             {
             if  (p[ti]>max2[i] )
              max2[i]=p[ti];}
          t=test[t].next; 
          }
     }
     if (vmax<max1[i]*max2[i] ) vmax=max1[i]*max2[i];
      
 }

void add(int u,int v,int w){
    test[cur].power = w;
    test[cur].to = v;
    test[cur].next = head[u];
    head[u] = cur++;
}
int main(){
    cin>>n;
    int u,v,w;
    for(int i = 0;i < n;i++){
         test[i].power = 1;
         test[i].next = -1;
         head[i] = -1;
         j[i] = 1;
    }
    int tu,tv;
    for(int i = 0;i < n-1;i++){
        cin>>tu>>tv;
        tu--;
        tv--;
        add(tu,tv,1);
        add(tv,tu,1);

    }
    for(int i = 0;i < n;i++) cin>>p[i];

    for(int i = 0;i < n;i++)use(i);    
    for(int i = 0;i < n;i++)dfs(i);
    cout<<vmax<<" "<<vall % 10007<<endl;
    return 0;
}

 

以上是关于codevs3728 联合权值的主要内容,如果未能解决你的问题,请参考以下文章

洛谷P1351codevs3728 联合权值

code3728 联合权值

poj3728(lca / tarjan离线)

POJ - 3728:The merchant (Tarjan 带权并查集)

codevs1922骑士共存问题——网络流

Codevs 1688 求逆序对(权值线段树)