zoukankan      html  css  js  c++  java
  • 2014年 联合权值

    联合权值
     
    题目描述
    无向连通图G 有n 个点,n - 1 条边。点从1 到n 依次编号,编号为 i 的点的权值为W i   ,每条边的长度均为1 。图上两点( u ,  v ) 的距离定义为u 点到v 点的最短距离。对于图G 上的点对( u, v) ,若它们的距离为2 ,则它们之间会产生Wu
    ×Wv 的联合权值。 
    请问图G 上所有可产生联合权值的有序点对中,联合权值最大的是多少?所有联合权值之和是多少?
     
    输入格式:
    输入文件名为link .in。 
    第一行包含1 个整数n 。 
    接下来n - 1 行,每行包含 2 个用空格隔开的正整数u 、v ,表示编号为 u 和编号为v 的点之间有边相连。 
    最后1 行,包含 n 个正整数,每两个正整数之间用一个空格隔开,其中第 i 个整数表示图G 上编号为i 的点的权值为W i 。
    输出格式:
    输出文件名为link .out 。 
    输出共1 行,包含2 个整数,之间用一个空格隔开,依次为图G 上联合权值的最大值
    和所有联合权值之和。由于所有联合权值之和可能很大,输出它时要对10007 取余。
     
    输入样例: 

    5
    1 2
    2 3
    3 4
    4 5
    1 5 2 3 10

    输出样例:
    20 74
     
     说明
     

    【数据说明】 
    对于30% 的数据,1 < n≤ 100 ; 
    对于60% 的数据,1 < n≤ 2000; 
    对于100%的数据,1 < n≤ 200 , 000 ,0 < wi≤ 10, 000 。
     
    //都知道(a+b)^2=a^2+2*a*b+b^2; 
    //那么2*a1a2+2*a1*a3+2*a1*a4...+2*a(n-1)*an=(a1+a2+a3+...+an)^2-a1^2-a2^2-a3^2-...-an^2;
    #include<cstdio>
    #include<vector>
    using namespace std;
    int n,x,y,sz[200002],i;
    bool f[200002];
    int ansx=0,ans;
    vector<int> map[200002];
    int main(){
        scanf("%d",&n);
        for(i=1;i<=n;i++) map[i].push_back(0);
        for(i=1;i<n;i++){
            scanf("%d%d",&x,&y);
            map[x][0]++;
            map[x].push_back(y);
            map[y][0]++;
            map[y].push_back(x);//保存各点所连接的点; 
        }
        for(i=1;i<=n;i++) scanf("%d",&sz[i]);
        for(i=1;i<=n;i++){
            if(map[i][0]>1){
                int max1=0,max2=0;
                int fh=0,hf=0,g=0;
                int j;
                for(j=1;j<=map[i][0];j++){//找到最大的值; 
                    if(sz[map[i][j]]>max1){
                        f[g]=0;
                        g=j;
                        max1=sz[map[i][j]];
                        f[j]=1;
                    }
                    hf=(hf+sz[map[i][j]])%10007;              //与第i个点相连的点的权值累和; 
                    fh=(fh+sz[map[i][j]]*sz[map[i][j]])%10007;//与第i个点相连的点的权值的平方和 
                }
                for(j=1;j<=map[i][0];j++) if(sz[map[i][j]]>max2&&!f[j]) max2=sz[map[i][j]];//找第二大的值;
                f[g]=0;
                if(max1*max2>ansx) ansx=max1*max2;           //储存最大值; 
                while(hf<fh) hf+=10007;                      //取模后和的平方可能小于平方和,故+10007; 
                hf*=hf;
                hf=(hf-fh)%10007;
                ans=(ans+hf)%10007;                        
            }
        }
        printf("%d %d
    ",ansx,ans);
        return 0;
    }
    View Code
  • 相关阅读:
    485串口接线
    mvc3 升级mvc5
    VB连接ACCESS数据库,使用 LIKE 通配符问题
    VB6 读写西门子PLC
    可用的 .net core 支持 RSA 私钥加密工具类
    解决 Win7 远程桌面 已停止工作的问题
    解决 WinForm 重写 CreateParams 隐藏窗口以后的显示问题
    解决安装 .net framework 发生 extracting files error 问题
    CentOS7 安装配置笔记
    通过特殊处理 Resize 事件解决 WinForm 加载时闪烁问题的一个方法
  • 原文地址:https://www.cnblogs.com/qingang/p/5348148.html
Copyright © 2011-2022 走看看