• CF11D A Simple Task(状压DP)


    传送门

    题意:给定一个简单图,输出其中的简单环的数目(简单环是不包含重复顶点、重复边的环)

    点数(1<=N<=19),边数(M>=1).保证不存在自环和重边.

    (f[S][i])表示:在点集S中,我们当前遍历到了i点,找到的简单环的数目.

    第一维S状态压缩,用二进制来枚举点(0表示该点还没走过,1表示该点已经走过.)

    因为点数最大不超过19,所以(S<=2^{19}=524288)

    设j表示下一个(我们要访问的)点,也就是与当前点i相连接,但不属于点集S的点.于是得到状态转移方程:

    (f[S|(1<<j)][j]+=f[S][i])

    而当j访问到点集S时,如果j回到了起点,则找到了环(之前肯定没有找到环,因为之前状态转移要求j不在点集S中,而起点就是在点集S中)

    总结一下上述:如果j不在点集S中,就状态转移(方程在上方);如果j在点集S中,就判断j是不是回到了起点,如果j是回到了起点,则说明找到了环,ans累加简单环的数目(f[S][i]).

    还有一些细节,直接结合代码来讲.

    int n,m,Map[20][20];
    long long ans,f[600005][20];
    int lowbit(int x){
        for(int i=0;i<n;i++)
    		if(x&(1<<i))return i;
    }
    int main(){
        n=read();m=read();
        for(int i=1;i<=m;i++){
    		int a=read()-1,b=read()-1;
    		Map[a][b]=1;Map[b][a]=1;
        }
    //因为我们二进制状态压缩,为了方便处理,
    //把点的编号[1,n]移到[0,n-1]中来.
    //直接用二维邻接表标记a,b两点间是否有边.
        for(int i=0;i<n;i++)
    		f[1<<i][i]=1;
    //初始化:
    //1<<i表示点集S中只有一个点i,此时又遍历到了点i
    //显然就是存在了一个环.
    //我们只能从当前不为0的状态转移到其它状态.
        for(int S=1;S<=(1<<n);S++)//枚举点集
    		for(int i=0;i<n;i++){//枚举点
    	    	if(!f[S][i])continue;
    //我们只能从当前不为0的状态转移到其它状态.
    	    	int p=lowbit(S);
    //p是点集S(二进制)中最低非零位的位置,
    //假设以该点为出发点,每次访问比它大的点作为下一点:
    	    	for(int j=p;j<n;j++){
    			if(!Map[i][j])continue;
    //S&(1<<j)表示j回到了点集S中:
    				if(S&(1<<j)){
    		    		if(j==p)ans+=f[S][i];
    //再判断是不是出发点,如果是的话,ans累加.
    				}
    				else f[S|(1<<j)][j]+=f[S][i];
    //如果j没有回到点集S,满足状态转移条件.
    	    }
    	}
        printf("%lld
    ",(ans-m)/2);
    //因为我们是在无向图中找简单环,所以一定会出现:
    //两个点一条边构成了一个非法环,即1---->2----->1
    //这里会产生m个非法环,所以ans要先减去边数m,
    //合法环会正向和反向计算两遍,所以还要除以2
        return 0;
    }
    
    
  • 相关阅读:
    好用的开源产品搜集;开源软件,开源系统,开源项目;
    windows10 双系统安装后,grub2 引导修复(亲自实验);grub2 命令行 手动加载内核;fedora 29 系统grub2引导修复;
    C 实战练习题目40
    C 实战练习题目39
    C 实战练习题目38
    C 实战练习题目37 – 排序
    C 实战练习题目36 – 求100之内的素数
    C 实战练习题目35 -字符串反转
    C 实战练习题目34
    C 实战练习题目33 – 质数(素数)判断
  • 原文地址:https://www.cnblogs.com/PPXppx/p/10323729.html
Copyright © 2020-2023  润新知