• 朝暮(枚举基准 容斥)


    朝暮(枚举基准 容斥)

    给出一个n个点,最多n+6条边的无向图,求将树黑白染色,且没有相邻黑点的方案数。(1leqslant nleqslant 10^5)

    首先,如果这个图是个树,就是个斯波dp。

    然后我在考试时想了个做法:枚举所有非树边旁边是00还是10还是01。复杂度(n3^n),成功tle。

    正解就好写得多。枚举旁边都是黑点的非树边有几条,容斥一下即可。

    我其实还没搞懂为什么还能这样容斥……果然自己计数题太弱了。

    注意((-1)^x)到底是啥!被坑了好久。

    #include <cstdio> 
    #include <cstring>
    using namespace std;
    
    const int maxn=1e5+10, mod=1e9+7;
    int n, m;
    struct Edge{
    	int to, nxt;
    }e[maxn*2];
    int fir[maxn], cnte;
    void addedge(int x, int y){
    	Edge &ed=e[++cnte];
    	ed.to=y; ed.nxt=fir[x]; fir[x]=cnte;
    }
    
    inline int popcount(int x){ int re=0;
    	while (x) re+=x&1, x>>=1;
    	return re; }
    
    int qd[maxn], ex[6], ey[maxn], cntext;
    long long f[maxn][2], ans;
    
    int fa[maxn];  //有向图求返祖边才需要dfs!无向图只需要并查集 
    int find(int x){ return fa[x]==x?x:fa[x]=find(fa[x]); }
    
    void dfs(int now, int par){
    	f[now][0]=f[now][1]=1;
    	if (qd[now]) f[now][0]=0;
    	for (int i=fir[now]; i; i=e[i].nxt){
    		if (e[i].to==par) continue;
    		dfs(e[i].to, now);
    		(f[now][0]*=(f[e[i].to][0]+f[e[i].to][1]))%=mod;
    		(f[now][1]*=f[e[i].to][0])%=mod;
    	}
    }
    
    int main(){
    	//freopen("20.in", "r", stdin); freopen("20.out", "w", stdout);
    	scanf("%d%d", &n, &m); int x, y;
    	for (int i=1; i<=n; ++i) fa[i]=i;
    	for (int i=1; i<=m; ++i){
    		scanf("%d%d", &x, &y);
    		if (find(x)==find(y)){ 
    			ex[cntext]=x; ey[cntext++]=y; 
    			continue;
    		}
    		addedge(x, y); addedge(y, x);
    		fa[find(x)]=find(y);
    	}
    	for (int i=0; i<(1<<cntext); ++i){
    		memset(f, 0, sizeof(f));
    		memset(qd, 0, sizeof(qd));
    		for (int j=0; j<cntext; ++j)
    			if (i&(1<<j)) qd[ex[j]]=qd[ey[j]]=1;
    		dfs(1, 0);
    		//要判断的是popcount的奇偶性! 
    		(ans+=(popcount(i)&1?-1:1)*(f[1][0]+f[1][1]))%=mod;
    	}
    	printf("%lld
    ", (ans+mod)%mod);
    	return 0;
    }
    
  • 相关阅读:
    快速分栏
    伪元素:before和:after的简单应用——清除浮动
    C# 调用事件
    C# 创建文件夹
    (C#-VisionPro)用代码方式新建VisionPro视觉文件(.vpp)
    C# 选择下拉框文件时触发
    C# 将指定目录下的文件夹名称加载到下拉框中
    (C#-VisionPro)用C#加载、保存ViaionPro的'.vpp'文件
    C# 关闭程序时保存程序数据
    (C#-VisionPro)用C#调用VisionPro保存的.vpp文件
  • 原文地址:https://www.cnblogs.com/MyNameIsPc/p/9459893.html
Copyright © 2020-2023  润新知