• bzoj3498: PA2009 Cakes


    题目描述:

    N个点m条边,每个点有一个点权a。
    对于任意一个三元环 $(i,j,k) (i<j<k)$ ,它的贡献
    为 $max(a_i,a_j,a_k)$  
    求所有三元环的贡献和。
    $Nle 100000,mle 250000$。

    算法标签:三元环

    思路:

    裸的三元环模板题拉。

    主要思路是按照度数排序对于双向边之连接度数大指向度数小的单向边,这样每个三元环只算一次。

    效率是 $O(nlogm+mlogm)$ 。

    以下代码:

    #include<bits/stdc++.h>
    #define il inline
    #define LL long long
    #define _(d) while(d(isdigit(ch=getchar())))
    using namespace std;
    const int N=1e5+5,M=25e4+5;
    LL ans;
    bool vis[N];
    int n,m,a[N],in[N],head[N],ne[M],to[M],cnt;
    struct node{
        int l,r;
    }t[M]; 
    il int read(){
        int x,f=1;char ch;
        _(!)ch=='-'?f=-1:f;x=ch^48;
        _()x=(x<<1)+(x<<3)+(ch^48);
        return f*x;
    }
    il void insert(int x,int y){
        ne[++cnt]=head[x];
        head[x]=cnt;to[cnt]=y;
    }
    int main()
    {
        n=read();m=read();
        for(int i=1;i<=n;i++)a[i]=read();
        for(int i=1;i<=m;i++){
            int x=read(),y=read();
            in[x]++;in[y]++;
            t[i]=(node){x,y};
        }
        for(int i=1;i<=m;i++){
            int x=t[i].l,y=t[i].r;
            if(in[x]<in[y]||(in[x]==in[y]&&x>y))swap(x,y);
            insert(x,y);
        }
        for(int x=1;x<=n;x++){
            for(int i=head[x];i;i=ne[i])vis[to[i]]=1;
            for(int i=head[x];i;i=ne[i]){
                int v=to[i];
                for(int j=head[v];j;j=ne[j]){
                    if(vis[to[j]]){
                        ans+=max(a[x],max(a[v],a[to[j]]));
                    }
                }
            }
            for(int i=head[x];i;i=ne[i])vis[to[i]]=0;
        }
        printf("%lld
    ",ans);
        return 0;
    }
    View Code
  • 相关阅读:
    浦东新区2019年下半年部分街镇社区工作者和部分单位编外人员公开招聘考试大纲
    苏州 山西
    第几行记录
    命令 检查Linux服务器性能
    SQLRecoverableException: I/O Exception: Connection reset
    Oracle单表备份三种方案
    vim 清空
    常看 Shell: 文本文件操作
    bash date format
    Linux Shell 截取字符串
  • 原文地址:https://www.cnblogs.com/Jessie-/p/10427835.html
Copyright © 2020-2023  润新知