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

    无向连通图G有n个点,n-1条边。点从1到n依次编号,编号为i的点的权值为Wi  ,每条边的长度均为1。图上两点(u, v)的距离定义为u点到v点的最短距离。对于图G上的点对(u, v),若它们的距离为2,则它们之间会产生Wu×Wv的联合权值。

    请问图G上所有可产生联合权值的有序点对中,联合权值最大的是多少?所有联合权值之和是多少?

    题目链接:codevs http://www.cnblogs.com/smileandyxu/p/5348411.html

    图论问题,70分暴力都很好打吧,只要枚举所有点dfs找到他的距离为二的点,维护一个tot和一个max就可以了,细节自己想想,代码

    等下会贴出来,正解是乘法的结合律,这个题目可以转换一下,对于每个点对,可以看成由一点中间点中转而成,就是每个点对中必定有

    且只隔一个点吧,因为图是棵树,只要枚举每个入度为1的点作为中转点,然后将其儿子与其他所有儿子相乘就可以了,但这是n平方的啊!会超时。

    所以我们用乘法原理,统计所有儿子权值和,然后用权值和剪去自己的权值的值再乘自己的权值,这样就是O(n)完成了。

    另外,推荐我的博客:http://www.cnblogs.com/renjianshige/

    暴力代码:

    #include<iostream>
    #include<stdio.h>
    #include<stdlib.h>
    #include<algorithm>
    #include<queue>
    #include<cstring> 
    const int MAXN=200010;
    using namespace std;
    struct edge{
        int first;
        int next;
        int to;
        int quan;
    }a[2*MAXN];
    bool b[MAXN];
    struct node{
        int now;
        int fa;
        node(){}
        node(int _now,int _fa):now(_now),fa(_fa){}
    };
    int dian[MAXN];
    int in[MAXN];
    int n,num=0;
    void addedge(int from,int to){
        a[++num].to=to;
        a[num].quan=1;
        a[num].next=a[from].first;
        a[from].first=num;
    }
    long long tott=0,big=0;
    void dfs(int now,int fa,int time){
        for(int i=a[now].first;i;i=a[i].next){
            int to=a[i].to;
            if(to==fa) continue;
            if(time==2){
                if(b[to]) continue;
                long long dianquan=dian[fa]*dian[to];
                big=max(big,dianquan);
                tott=(tott+dianquan)%10007;
                continue; 
            }
            dfs(to,now,time+1);
        }
    }
    int main(){
        memset(dian,0,sizeof(dian));
        memset(b,0,sizeof(b));
        scanf("%d",&n);
        for(int i=1;i<n;i++){
            int x,y;
            scanf("%d%d",&x,&y);
            addedge(x,y);
            addedge(y,x);
        }
        for(int i=1;i<=n;i++){
            scanf("%d",&dian[i]);
        }
        for(int i=1;i<=n;i++){
            dfs(i,0,1);
            b[i]=1;
        }
        printf("%lld %lld
    ",big,(tott*2)%10007);
        return 0;
    }

    AC代码:

    #include<iostream>
    #include<stdio.h>
    #include<stdlib.h>
    #include<algorithm>
    #include<queue>
    #include<cstring>
    const int MAXN=200010;
    using namespace std;
    struct edge{
        int first;
        int next;
        int to;
        int quan;
    }a[2*MAXN];
    bool b[MAXN];
    int dian[MAXN];
    int in[MAXN];
    int n,num=0;
    void addedge(int from,int to){
        a[++num].to=to;
        a[num].quan=1;
        a[num].next=a[from].first;
        a[from].first=num;
    }
    long long tott=0,big=0;
    void dfs(int now){
      long long tot=0,big1=0,big2=0;
        for(int i=a[now].first;i;i=a[i].next){
            int to=a[i].to;
            tot=(tot+dian[to])%10007;
            if(dian[to]>big1)
              {
                big1=dian[to];
                continue;
              }
            if(dian[to]<=big1&&dian[to]>big2) big2=dian[to];
        }
        for(int i=a[now].first;i;i=a[i].next){
          tott+=dian[a[i].to]*(tot-dian[a[i].to])%10007;
          if(tott<0) tott+=10007;
          tott=tott%10007;
        }
        if(big<big1*big2) big=big1*big2;
    }
    int main(){
        memset(dian,0,sizeof(dian));
        memset(b,0,sizeof(b));
        scanf("%d",&n);
        for(int i=1;i<n;i++){
            int x,y;
            scanf("%d%d",&x,&y);
            addedge(x,y);
            addedge(y,x);
            in[x]++;
            in[y]++;
        }
        for(int i=1;i<=n;i++){
            scanf("%d",&dian[i]);
        }
        for(int i=1;i<=n;i++){
          if(in[i]==1) continue;
          dfs(i);
        }
        printf("%lld %lld
    ",big,tott%10007);
        return 0;
    }
  • 相关阅读:
    python+opencv实现图像自适应阈值的均衡化
    ubuntu添加新的分辨率选项(干货)
    python+opencv检测图像清晰度
    python根据列表创建文件夹,拷贝指定文件
    牛客多校Round 4
    牛客多校Round 3
    HDU多校Round 2
    HDU多校Round 1
    牛客多校Round 2
    牛客多校Round 1
  • 原文地址:https://www.cnblogs.com/renjianshige/p/6995582.html
Copyright © 2011-2022 走看看