zoukankan      html  css  js  c++  java
  • 题解[CF53E Dead Ends]

    题目

    CF

    Luogu

    不会翻译也不会概括

    要说的话

    最近一直在考试,没有什么时间来做讲课的题,分享的题,好不容易有时间做一道喜欢的题,好题。

    浮云吹作雪,世味煮成茶。

    Sol

    注意到数据范围(n=10)马上经过反复考虑可以用状压。

    (f[i][j])为:目前树的状态为(i) ,叶子节点的状态为(j)的方案数。

    (i)的二进制第(k)位是(1)表示树上有第(k)个节点,(j)的二进制第(k)位是(1)表示。

    所以,我们最好在连边的时候把每个点的编号-1,以便二进制存储。

    状态转移时注意判断一下叶子节点就好了。

    Code

    #include<bits/stdc++.h>
    #define ll long long
    #define S (1025)
    #define V (1024)
    #define M (110)
    #define N (11)
    using namespace std;
    struct xbk{int ed,nx;}e[M];
    int n,m,k,cnt;
    ll ans;
    int head[N],num[S],f[S][S];
    inline int read(){
    	int w=0;
    	char ch=getchar();
    	while(ch>'9'||ch<'0') ch=getchar();
    	while(ch>='0'&&ch<='9'){
    		w=(w<<3)+(w<<1)+(ch^48);
    		ch=getchar();
    	}
    	return w;
    }
    inline void add(int a,int b){
    	e[++cnt].ed=b;
    	e[cnt].nx=head[a];
    	head[a]=cnt;
    }
    int main(){
    	n=read(),m=read(),k=read();
    	memset(head,-1,sizeof(head));
    	for(int i=1;i<=V;i++)
    		for(int j=0;j<15;j++) if(i&(1<<j)) num[i]++;
      //初始状态:树上只有一个节点,方案数为一
    	for(int i=1;i<(1<<n);i<<=1) f[i][i]=1;
    	for(int i=1;i<=m;i++){
    		int x=read()-1,y=read()-1;
    		add(x,y),add(y,x);
    	}
    	for(int i=1;i<(1<<n);i++){
    		for(int j=i;j;j--,j&=i){
              //j:枚举叶子的状态
    			if(!f[i][j]) continue;
    			for(int k=0;k<n;k++){
                  //k:枚举树上的节点
    				if(!(i&(1<<k))) continue;
    				for(int l=head[k];~l;l=e[l].nx){
                      //l:枚举这个节点所连的边
    					int ed=e[l].ed,now=0;
                      //now:连边后叶子的状态
    					if(i&(1<<ed)) continue;
                      //如果树上已经有这个点了,就跳过
    					if(num[i]==1) now=i|(1<<ed);
                      //如果树上目前只有一个点,那连边之后两个点都是叶子
    					else now=(j&(~(1<<k)))|(1<<ed);
                      //否则,ed一定是叶子,k如果原来是叶子,那现在就不是叶子
    					if(!(now>>(ed+1))) f[i|(1<<ed)][now]+=f[i][j];
                      //更新状态
    				}
    			}
    		}
    	}
    	for(int i=0;i<(1<<n);i++)
    		if(num[i]==k) ans+=f[(1<<n)-1][i];
      //统计答案
    	printf("%lld
    ",ans);
    	return 0;
    }
    

    完结撒花❀

  • 相关阅读:
    Android 定制RadioButton样式
    TabActivity的不同实现
    android源码的目录
    让我们一起来做最漂亮的Android界面
    【Android布局】在程序中设置android:gravity 和 android:layout_Gravity属性
    iPhone iPad 各种控件默认高度
    互联网的的一些历史资料收集
    Android vs iPhone icon设计指南
    android获取手机cpu是单核还是多核的方法
    前端必读:浏览器内部工作原理
  • 原文地址:https://www.cnblogs.com/xxbbkk/p/14545972.html
Copyright © 2011-2022 走看看