zoukankan      html  css  js  c++  java
  • 【BZOJ3498】[PA2009] Cakes(某黑科技)

    点此看题面

    大致题意: 对于所有三元环,求三个顶点的最大权值之和。

    黑科技——三元环

    印象里这个黑科技好像在谁讲课的时候介绍过,是个很巧妙但不常见的技巧。

    考虑如何高效且不重不漏地枚举三元环。

    我们统计每个点的度数,然后人为给无向边定向,从度数小的点向度数大的点连边(度数相同时从编号小向编号大连边)。

    这样一来第一个好处就是,一张无向图被我们转化为了(DAG)

    求解时,我们枚举每一个点(i),然后枚举每一个它连向的点(j)打上标记。接着再次枚举每一个它连向的点(j),并继续枚举(j)连向的点(k),如果(k)被打了标记,则((i,j,k))必然是一个三元环。

    正确性应该比较显然,复杂度证明可以用根号思想:

    • 如果(deg_ilesqrt m),复杂度显然是(O(sqrt m))的。
    • 如果(deg_i>sqrt m),由于它连向的点度数一定大于(deg_i),也就大于(sqrt m),最多只有(sqrt m)个,复杂度也是(O(sqrt m))

    因此总复杂度(O(msqrt m))

    此题做法

    根据上面的黑科技,直接枚举每一个三元环,统计答案即可。

    这题应该可以算是这种黑科技的板子题?

    代码

    #include<bits/stdc++.h>
    #define Tp template<typename Ty>
    #define Ts template<typename Ty,typename... Ar>
    #define Reg register
    #define RI Reg int
    #define Con const
    #define CI Con int&
    #define I inline
    #define W while
    #define N 100000
    #define M 250000
    #define add(x,y) (e[++ee].nxt=lnk[x],e[lnk[x]=ee].to=y)
    using namespace std;
    int n,m,a[N+5],d[N+5],f[N+5],x[M+5],y[M+5],ee,lnk[N+5];struct edge {int to,nxt;}e[2*M+5];
    class FastIO
    {
    	private:
    		#define FS 100000
    		#define tc() (A==B&&(B=(A=FI)+fread(FI,1,FS,stdin),A==B)?EOF:*A++)
    		#define D isdigit(c=tc())
    		char c,*A,*B,FI[FS];
    	public:
    		I FastIO() {A=B=FI;}
    		Tp I void read(Ty& x) {x=0;W(!D);W(x=(x<<3)+(x<<1)+(c&15),D);}
    		Ts I void read(Ty& x,Ar&... y) {read(x),read(y...);}
    }F;
    int main()
    {
    	RI i,j,k;for(F.read(n,m),i=1;i<=n;++i) F.read(a[i]);
    	for(i=1;i<=m;++i) F.read(x[i],y[i]),++d[x[i]],++d[y[i]];//计算度数
    	for(i=1;i<=m;++i) (d[x[i]]^d[y[i]]?d[x[i]]<d[y[i]]:x[i]<y[i])?add(x[i],y[i]):add(y[i],x[i]);//人为定向
    	long long ans=0;for(i=1;i<=n;++i)//枚举点
    	{
    		for(j=lnk[i];j;j=e[j].nxt) f[e[j].to]=i;//打标记
    		for(j=lnk[i];j;j=e[j].nxt) for(k=lnk[e[j].to];k;k=e[k].nxt)//枚举再枚举
    			f[e[k].to]==i&&(ans+=max(a[i],max(a[e[j].to],a[e[k].to])));//找到三元环计算贡献
    	}return printf("%lld",ans),0;
    }
    
  • 相关阅读:
    输入框实时验证是否跟后台数据重复,重复的话在输入框下边提示该名称已存在
    表格某一列内容需要占据两列宽度,如何设置样式以及只给某一列添加边框
    Dropdown 下拉菜单 修改为 select 框样式,在框内显示图片,并且二次确认,选取消依旧显示原来选项
    常用的正则表达式
    vue element UI 添加一行表单
    Cannot read property 'reduce' of null 报错解决
    vue 打包卡住的问题
    vue 安装scss 报错 TypeError: this.getResolve is not a function 解决
    解压版mysql安装(windows版)
    外部系统调用星空接口
  • 原文地址:https://www.cnblogs.com/chenxiaoran666/p/BZOJ3498.html
Copyright © 2011-2022 走看看