• Projecteuler522 Hilbert's Blackout


    Hilbert's Blackout

    (n) 个点,每个点随机连向和它不同的点。定义一个图的代价为最少所需点数使得改这么多个点的出边后能让它变成一个大环。

    求所有图的总代价。(n=10^7)

    题解

    https://titanwolf.org/Network/Articles/Article?AID=0d201ef5-6157-4a52-861a-11d934f87266

    For a component, if

    1. it's a cycle of size < n, we need to rewire 1 floor;

    2. it's a cycle of size n, we've finished!

    3. otherwise, we need to rewire (sum (max(indeg_i, outdeg_i) - 1)) floors.

    根据期望的线性性,我们仍然可以把不同种的贡献分开计算。

    算环的式子:

    [sum_{i=2}^{n-2}inom{n}{i}(i-1)! imes (n-i-1)^{n-i} ]

    先枚举环的大小,枚举到 (n-2) 是因为剩余一个点的时候它只能自己连向自己。然后乘上环的组成,环上的顺序。再乘上其他点的连边方式。

    算非环连通块的式子:

    [sum_{i=2}^{n-1}(i-1) imes ninom{n-1}{i} imes (n-1)(n-2)^{n-1-i} ]

    枚举入度的大小,乘上固有贡献。然后乘上被连的点是哪个,连边的点的组成。再乘上被连的点连向哪个,其他的点的连边方式。

    CO int N=12344321+10;
    int fac[N],ifac[N];
    
    IN int binom(int n,int m){
    	return mul(fac[n],mul(ifac[m],ifac[n-m]));
    }
    int main(){
    	int n=12344321;
    	fac[0]=1;
    	for(int i=1;i<=n;++i) fac[i]=mul(fac[i-1],i);
    	ifac[n]=fpow(fac[n],mod-2);
    	for(int i=n-1;i>=0;--i) ifac[i]=mul(ifac[i+1],i+1);
    	
    	int ans=0;
    	for(int i=2;i<=n-2;++i)
    		ans=add(ans,mul(binom(n,i),mul(fac[i-1],fpow(n-i-1,n-i))));
    	for(int i=2;i<=n-1;++i)
    		ans=add(ans,mul(i-1,mul(binom(n-1,i),mul(fpow(n-2,n-1-i),mul(n-1,n)))));
    	printf("%d
    ",ans);
    	return 0;
    }
    

    上课的时候杜老师讲代价=叶子个数+环个数。然后说算入度太麻烦。

    但是当只有一个环的时候,代价要-1。这样反而不好计算了。

  • 相关阅读:
    安卓开发_浅谈TimePicker(时间选择器)
    eclipse显示代码行数
    Java数据解析---JSON
    Java数据解析---PULL
    Java数据解析---SAX
    统计机器学习(目录)
    FP Tree算法原理总结
    梯度下降(Gradient Descent)小结
    用scikit-learn和pandas学习线性回归
    用scikit-learn学习BIRCH聚类
  • 原文地址:https://www.cnblogs.com/autoint/p/12114335.html
Copyright © 2020-2023  润新知