欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

联合权值(link)

程序员文章站 2022-05-22 14:34:50
...

洛谷p1351
NOIP2014 day1 T2

题目概述

无向连通图 G 有 n 个点,n-1 条边。点从 1 到 n 依次编号,编号为 i 的点的权值为 w[i] ,每条边的长度均为 1。图上两点(u, v)的距离定义为 u 点到 v 点的最短距离。对于图 G 上的点对(u, v),若它们的距离为 2,则它们之间会产生w[u]*w[v]的联合权值。请问图 G 上所有可产生联合权值的有序点对中,联合权值最大的是多少?所有联合权值之和是多少?

题解

由于此题只需要把距离为2的边统计出来,因此可以把每一类距离为2的边分类讨论。显然,这道题是一棵树。可以看出,这种边只有两种,一种是祖先-父亲-儿子(以下称祖孙边),另一种是同一个父亲的兄弟边。对于祖孙边,很好处理,对于要处理的点,把每个孙子点列出来,祖孙边的权值就知道了。对于兄弟边,只要把当前处理的点的每一个儿子都遍历一遍,经过父亲和其它儿子点就自然而然是一条兄弟边。如果要每一个儿子点和其它每一个儿子点都做一遍,时间复杂度太高了,所以可以用前缀和。至于最大权值,可以把最大的两个点记录下来,它们的联合权值肯定是这些兄弟边中最大的。
看程序吧:

#include<iostream>
#include<cstdio>
#include<vector>
using namespace std;
int n,w[200005],ans,s,b[200005];//s表示联合权值和,ans表示最大联合权值 
vector<int> a[200005];
void dfs(int x)
{
    b[x]=1;//已做过就标记掉 
    int t1=0,t2=0,t=0;//t表示前缀和,t1表示儿子点中的最大权值,t2表示次大权值 
    for (int i=0;i<a[x].size();i++)//遍历儿子点 
    {
        if (b[a[x][i]]!=0) continue;//因为是无向图,避免做到父亲点 
        if (w[a[x][i]]>t1)//记录最大值和次大值 
        {
            t2=t1;
            t1=w[a[x][i]];
        }
        else if (w[a[x][i]]>t2) t2=w[a[x][i]];
        s=(s+w[a[x][i]]*t%10007)%10007;//处理兄弟边 
        t+=w[a[x][i]];//维护前缀和 
        t%=10007;//如果不做这一步会超过INT_MAX,然后就错了 
        for (int j=0;j<a[a[x][i]].size();j++)//处理祖孙边 
        {
            int y=a[a[x][i]][j];
            if (b[y]!=0) continue;
            s=(s+w[x]*w[y]%10007)%10007;
            ans=max(ans,w[x]*w[y]);
        }
    }
    ans=max(ans,t1*t2);
    for (int i=0;i<a[x].size();i++) if (b[a[x][i]]==0) dfs(a[x][i]);
}
int main()
{
    cin>>n;
    int x,y;
    for (int i=1;i<n;i++)
    {
        scanf("%d %d",&x,&y);
        a[x].push_back(y);//邻接表存边,无向边,所以要做两次 
        a[y].push_back(x);
    }
    for (int i=1;i<=n;i++) scanf("%d",&w[i]);
    dfs(1);//假设1号点为树根 
    cout<<ans<<' '<<s*2%10007;//前面都是单向做的,所以答案要乘以2 
}

总结

这道题虽然不是很难,但我初测只有40分。我以为每一步都mod 10007,最后就不用了,测了样例之后才想到要乘以2,可忘记还要mod 10007。改了之后还是只有70分,原来是前缀和在计算的时候没有mod 10007,这样就超过了INT_MAX,前缀和就变成了负数。这次题目没做好,原因还是细节没有处理好。以后遇到mod的题目可一定要小心,每一步都要注意mod。

上一篇: 联合权值

下一篇: 图论模板