• 【LOJ #2290】「THUWC 2017」随机二分图(状压DP)


    传送门

    暴力的做法是设f[s1][s2]f[s1][s2]为左右匹配状态转移

    考虑对于第二类
    拆成两条独立的,出现概率为50%50\%的边
    但是一起出现的概率少了25%25\%
    可以再加一个一起出现的25%25\%的情况

    第三类类似
    加一个一起出现为25%-25\%的情况

    然后暴力dpdp,用mapmap存状态
    每次匹配标号最小的一个点
    这样复杂度也是对的

    #include<bits/stdc++.h>
    using namespace std;
    #define cs const
    #define re register
    #define pb push_back
    #define pii pair<int,int>
    #define fi first
    #define se second
    #define ll long long
    #define poly vector<int>
    #define bg begin
    cs int RLEN=1<<20|1;
    inline char gc(){
    	static char ibuf[RLEN],*ib,*ob;
    	(ib==ob)&&(ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
    	return (ib==ob)?EOF:*ib++;
    }
    inline int read(){
    	char ch=gc();
    	int res=0;bool f=1;
    	while(!isdigit(ch))f^=ch=='-',ch=gc();
    	while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=gc();
    	return f?res:-res;
    }
    template<class tp>inline void chemx(tp &a,tp b){a<b?a=b:0;}
    template<class tp>inline void chemn(tp &a,tp b){a>b?a=b:0;}
    cs int mod=1e9+7;
    inline int add(int a,int b){return (a+=b)>=mod?(a-mod):a;}
    inline int dec(int a,int b){a-=b;return a+(a>>31&mod);}
    inline int mul(int a,int b){static ll r;r=1ll*a*b;return r>=mod?(r%mod):r;}
    inline void Add(int&a,int b){a+=b,a>=mod?(a-=mod):0;}
    inline void Dec(int &a,int b){a-=b,a+=a>>31&mod;}
    inline void Mul(int &a,int b){static ll r;r=1ll*a*b;a=(r>=mod)?(r%mod):r;}
    inline int ksm(int a,int b,int res=1){for(;b;b>>=1,Mul(a,a))(b&1)&&(Mul(res,a),1);return res;}
    inline int Inv(int x){return ksm(x,mod-2);}
    cs int N=17,M=305;
    cs int inv2=Inv(2),inv4=Inv(4);
    map<int,int>f;
    int n,m,tot,lim;
    struct trans{
    	int s,coef;
    }p[M];
    int dfs(int sta){
    	if(sta==lim)return 1;
    	if(f.count(sta))return f[sta];
    	int mnpos=0,res=0;
    	for(int i=0;i<n;i++)if(!(sta&(1<<i))){mnpos=1<<i;break;}
    	for(int i=1;i<=tot;i++)
    	if((p[i].s&mnpos)&&!(sta&p[i].s))
    	Add(res,mul(dfs(sta|p[i].s),p[i].coef));
    	return f[sta]=res;
    }
    int main(){
    	#ifdef Stargazer
    	freopen("lx.cpp","r",stdin);
    	#endif
    	n=read(),m=read(),lim=(1<<(2*n))-1;
    	for(int i=1;i<=m;i++){
    		int op=read(),a=read()-1,b=read()-1;
    		p[++tot].coef=inv2,p[tot].s=((1<<a)|(1<<(b+n)));
    		if(op){
    			int x=read()-1,y=read()-1;
    			p[++tot].coef=inv2,p[tot].s=((1<<x)|(1<<(y+n)));
    			if(x==a||y==b)continue;
    			p[++tot].s=((1<<x)|(1<<(y+n))|(1<<a)|(1<<(b+n)));
    			if(op==1)p[tot].coef=inv4;else p[tot].coef=mod-inv4;
    		}
    	}
    	cout<<mul(ksm(2,n),dfs(0));
    }
    
  • 相关阅读:
    js总结:增加和减少文本框
    java总结:字符串切割
    Spring-----ioc
    Hibernate之二级缓存
    Hibernate之HQL
    Hibernate关联关系(一对多自关联 ,多对多)
    Hibernate关联关系(一对多)
    Hibernate之主键生成策略
    如何使用hibernate完成CRUD操作
    Struts2-----文件上传与拦截器原理
  • 原文地址:https://www.cnblogs.com/stargazer-cyk/p/12328365.html
Copyright © 2020-2023  润新知