zoukankan      html  css  js  c++  java
  • BZOJ2560 串珠子

    题意

    铭铭有n个十分漂亮的珠子和若干根颜色不同的绳子。现在铭铭想用绳子把所有的珠子连接成一个整体。
    
    现在已知所有珠子互不相同,用整数1到n编号。对于第i个珠子和第j个珠子,可以选择不用绳子连接,或者在ci,j根不同颜色的绳子中选择一根将它们连接。如果把珠子看作点,把绳子看作边,将所有珠子连成一个整体即为所有点构成一个连通图。特别地,珠子不能和自己连接。
    
    铭铭希望知道总共有多少种不同的方案将所有珠子连成一个整体。由于答案可能很大,因此只需输出答案对1000000007取模的结果。
    

    (n leq 16)

    分析

    参考SFN1036的题解。

    题意即:给出一个大小为n的无向图,边有边权。定义一个子图的权值为所有边权的乘积,问所有使全部n个点连通的子图的权值和为多少。

    (f(s))表示使(s)中的点连通且不管其余点的所有子图的权值和为多少,(g(s))表示只看集合(s)中的点,所有子图的权值和是多少。

    显然(g(s))可以预处理,考虑如何求(f(s))

    直接求显然不好求,考虑用所有方案减去不合法的方案。按照套路,我们可以枚举编号最小的点所在的连通块,设为集合(t),那么

    [f(s)=g(s)-sum_{t}f(t) cdot g(s-t) ]

    时间复杂度(O(n2^n + 3^n))

    关于基准点的问题

    不重

    直接枚举子集会有重复的情况。具体而言重复的是“f枚举到了 原来的g的子集 ,然后g包含 原来的f 和 现在的f在原来的g中的补集 ”。

    然后不找基准点的话就会重复,设想对于一种连通块个数确定的情况,会重复连通块个数那么多次。

    然后确定了一个基准点以后,f就不可能再是g的子集了,所以不会重复。

    不漏

    由于不连通一定可以看成包含基准点的连通块与其他连通块不连通,所以不会遗漏。

    无另解

    每种情况的每个连通块都会作为t被计算一次,所以是连通块个数次。

    但是所说的每种情况并未在状态中体现,所以虽然单个情况的确重复了连通块个数次,但是总体考虑是无法确定具体重复了多少次的。

    也就是说没法通过不确定基准点计算,然后减去重复的情况这么做

    %出题人

    sto 出题人 orz

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cmath>
    #include<set>
    #include<map>
    #include<queue>
    #include<stack>
    #include<algorithm>
    #include<bitset>
    #include<cassert>
    #include<ctime>
    #include<cstring>
    #define rg register
    #define il inline
    #define co const
    template<class T>il T read()
    {
    	rg T data=0;
    	rg int w=1;
    	rg char ch=getchar();
    	while(!isdigit(ch))
    	{
    		if(ch=='-')
    			w=-1;
    		ch=getchar();
    	}
    	while(isdigit(ch))
    	{
    		data=data*10+ch-'0';
    		ch=getchar();
    	}
    	return data*w;
    }
    template<class T>T read(T&x)
    {
    	return x=read<T>();
    }
    using namespace std;
    typedef long long ll;
    
    co int MAXN=16,mod=1e9+7;
    int n,c[MAXN][MAXN];
    
    int log2(int x)
    {
    	int res=-1;
    	while(x)
    	{
    		x>>=1;
    		++res;
    	}
    	return res;
    }
    
    int add(int x,int y)
    {
    	x+=y;
    	return x>=mod?x-mod:x;
    }
    
    int sub(int x,int y)
    {
    	x-=y;
    	return x<0?x+mod:x;
    }
    
    int mul(int x,int y)
    {
    	return (ll)x*y%mod;
    }
    
    int f[1<<MAXN],g[1<<MAXN];
    
    int main()
    {
    //	freopen(".in","r",stdin);
    //	freopen(".out","w",stdout);
    	read(n);
    	for(int i=0;i<n;++i)
    		for(int j=0;j<n;++j)
    			read(c[i][j]);
    	g[0]=1;
    	for(int i=1;i<(1<<n);++i)
    	{
    		int x=log2(i&-i);
    //		cerr<<"x="<<x<<endl;
    		g[i]=g[i-(1<<x)];
    		for(int j=0;j<n;++j)
    			if(i&(1<<j))
    				g[i]=mul(g[i],c[x][j]+1);
    //		cerr<<i<<" g="<<g[i]<<endl;
    	}
    	g[0]=0;
    	for(int i=1;i<(1<<n);++i)
    	{
    		f[i]=g[i];
    		int x=i&-i,s=i-x;
    		for(int j=s;j>=0;j=!j?-1:(j-1)&s)
    			f[i]=sub(f[i],mul(f[x+j],g[s-j]));
    //		cerr<<i<<" f="<<f[i]<<endl;
    	}
    	printf("%d
    ",f[(1<<n)-1]);
    	return 0;
    }
    
  • 相关阅读:
    redis启动
    supervisor thinkphp6 qune
    iview table header cell tooltip; iview表格 表头、单元格文字提示 ;iview 表格 悬浮提示
    .net mvc 中引入 echarts dataTool prepareBoxplotData
    iview table 初始化为null问题
    sqlserver 视图 EF无法从数据更新模型
    sql 空格变问号;sql 无法 去掉 空格 ;sql rtrim 失效;(转载)
    MongoDB的备份与恢复(转载)
    jQuery的deferred对象详解(转载)
    今天,我们小公司的服务器被黑了!!!
  • 原文地址:https://www.cnblogs.com/autoint/p/10025280.html
Copyright © 2011-2022 走看看