zoukankan      html  css  js  c++  java
  • 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。这样反而不好计算了。

  • 相关阅读:
    有上下界的可行流
    NOIP模拟——change
    NOIP模拟 ———number(假的数位dp)
    18.8.18NOIP模拟。。。。Snow
    字符串算法(KMP,Trie树,AC自动机)
    BZOJ4293 Siano
    NOIP2017 DAY2 T1
    AtCoder Grand Contest 023 D GO Home
    浅谈SPFA(队列优化的Bellman-Ford算法)
    最短路最基本算法———Floyd算法
  • 原文地址:https://www.cnblogs.com/autoint/p/12114335.html
Copyright © 2011-2022 走看看