BZOJ 3498 PA2009 Cakes

本文介绍了一种解决无向图中特定三元环计数问题的方法,通过构建有向图模型来简化计算过程,并分析了其时间复杂度为O(n√m)。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本题BZOJ权限题,但在bzojch上可以看题面。

题意:

  N个点m条无向边,每个点有一个点权a。

  对于任意一个三元环(i,j,k)(i<j<k),它的贡献为max(ai,aj,ak) 

  求所有三元环的贡献和。

  N<100000,m<250000

Solution:

  本题裸的三元环计数。

  无向图三元环计数的问题大致做法:

    统计每个点的度数,对于一条无向边$<u,v>$,若$deg[u]==deg[v]$则从编号小的点向编号大的点连有向边,否则从$deg$较大的向较小的点连有向边。

    这样无向图就变为了一个DAG模型,然后扫一下每个点$u$,对其出点$v$打标记$vis[v]=u$,再对每个出点$v$的出点$w$判断是否满足$vis[w]=u$即可。

  分析一波时间复杂度:

    不难发现对于每条边$u\rightarrow v$,我们需要统计的是出度个数$out_v$,那么总的贡献是$\sum_\limits{i=1}^{i\leq n}{out_i}$。

    假设$out_v\leq \sqrt m$,由于$u\rightarrow v$,则$deg_u\geq deg_v$,这样$u$最多$n$个,于是此时最坏复杂度为$O(n\sqrt m)$;

    假设$out_v>\sqrt m$,由于$u\rightarrow v$,则$deg_u\geq deg_v$,于是$deg_u>\sqrt m$,这样$u$最多$\sqrt m$个,于是此时最坏时间复杂度$O(m\sqrt m)$。

  综上所述,$n,m$同阶时,该算法时间复杂度$O(n\sqrt m)$。

  那么本题三元环计数时累加答案就好了。

代码:

 

/*Code by 520 -- 9.10*/
#include<bits/stdc++.h>
#define il inline
#define ll long long
#define RE register
#define For(i,a,b) for(RE int (i)=(a);(i)<=(b);(i)++)
#define Bor(i,a,b) for(RE int (i)=(b);(i)>=(a);(i)--)
using namespace std;
const int N=500005;
int n,m,a[N],deg[N],vis[N];
int to[N],net[N],h[N],cnt;
struct node{
    int u,v;
}e[N];
ll ans;

int gi(){
    int a=0;char x=getchar();bool f=0;
    while((x<'0'||x>'9')&&x!='-')x=getchar();
    if(x=='-')x=getchar(),f=1;
    while(x>='0'&&x<='9')a=(a<<3)+(a<<1)+(x^48),x=getchar();
    return f?-a:a;
}

il void add(int u,int v){to[++cnt]=v,net[cnt]=h[u],h[u]=cnt;}

int main(){
    n=gi(),m=gi();
    For(i,1,n) a[i]=gi();
    For(i,1,m) e[i].u=gi(),e[i].v=gi(),++deg[e[i].u],++deg[e[i].v];
    For(i,1,m) {
        RE int u=e[i].u,v=e[i].v;
        if(deg[u]<deg[v]||deg[u]==deg[v]&&u>v) swap(u,v);
        add(u,v);
    }
    For(u,1,n){
        for(RE int i=h[u];i;i=net[i]) vis[to[i]]=u;
        for(RE int i=h[u];i;i=net[i]) {
            RE int v=to[i];
            for(RE int j=h[v];j;j=net[j]){
                RE int w=to[j];
                if(vis[w]==u)ans+=max(a[u],max(a[v],a[w]));
            }
        }
    }
    cout<<ans;
    return 0;
}

 

转载于:https://www.cnblogs.com/five20/p/9622701.html

资源下载链接为: https://pan.quark.cn/s/22ca96b7bd39 在当今的软件开发领域,自动化构建与发布是提升开发效率和项目质量的关键环节。Jenkins Pipeline作为一种强大的自动化工具,能够有效助力Java项目的快速构建、测试及部署。本文将详细介绍如何利用Jenkins Pipeline实现Java项目的自动化构建与发布。 Jenkins Pipeline简介 Jenkins Pipeline是运行在Jenkins上的一套工作流框架,它将原本分散在单个或多个节点上独立运行的任务串联起来,实现复杂流程的编排与可视化。它是Jenkins 2.X的核心特性之一,推动了Jenkins从持续集成(CI)向持续交付(CD)及DevOps的转变。 创建Pipeline项目 要使用Jenkins Pipeline自动化构建发布Java项目,首先需要创建Pipeline项目。具体步骤如下: 登录Jenkins,点击“新建项”,选择“Pipeline”。 输入项目名称和描述,点击“确定”。 在Pipeline脚本中定义项目字典、发版脚本和预发布脚本。 编写Pipeline脚本 Pipeline脚本是Jenkins Pipeline的核心,用于定义自动化构建和发布的流程。以下是一个简单的Pipeline脚本示例: 在上述脚本中,定义了四个阶段:Checkout、Build、Push package和Deploy/Rollback。每个阶段都可以根据实际需求进行配置和调整。 通过Jenkins Pipeline自动化构建发布Java项目,可以显著提升开发效率和项目质量。借助Pipeline,我们能够轻松实现自动化构建、测试和部署,从而提高项目的整体质量和可靠性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值