标签:wedge 洛谷 一组 int s2 s1 P4547 15 THUWC2017
题解
考虑一个完美匹配出现的概率 $\times 2^n$ 对答案的贡献,初始是 $1$ ,如果有出现一组 $t=2$ 的边的话,那贡献就是 $0$ ,否则每出现一组 $t=1$ 的边就要 $\times 2$ ,所以有个暴力的 $\text{dp}$ : $f[s1][s2]$ 表示左边出现点的状态为 $s1$ ,右边为 $s2$ 的答案,为了避免重复我们每次挑 $s1$ 中编号最小的点进行转移,即 $f[s1][s2]=\sum_{y \in s2}f[s1 \wedge x][s2 \wedge y]$ ,考虑如果 $(x,y)$ 有一组 $t=1$ 的边 $(u,v)$ 也在 $s1,s2$ 集合中的话,那要再加上 $f[s1 \wedge x \wedge u][s2 \wedge y \wedge v]$ ,反之如果有一组 $t=2$ 的在集合中的话就要扣掉,记忆化搜索即可。
代码
#include <bits/stdc++.h> using namespace std; const int P=1e9+7;map<int,int>f; int n,m,k,a[15][15],c[1<<15],b[15][15][2]; int X(int x){return x>=P?x-P:x;} int F(int i,int j){ if (f.count(i<<n|j)) return f[i<<n|j]; int w=0,x=i&-i,u,v; for (int y=j&-j,k=j;k;k^=y,y=k&-k){ if (!~a[c[x]][c[y]]) continue; w=X(w+F(i^x,j^y)); u=b[c[x]][c[y]][0];v=b[c[x]][c[y]][1]; if (a[c[x]][c[y]] && (u&i) && (v&j) && u!=x && v!=y){ if (a[c[x]][c[y]]&1) w=X(w+F(i^x^u,j^y^v)); else w=X(w+P-F(i^x^u,j^y^v)); } } return f[i<<n|j]=w; } int main(){ cin>>n>>m;k=1<<n; for (int i=0;i<n;i++) c[1<<i]=i; memset(a,-1,sizeof a); for (int x,y,u,v,o,i=1;i<=m;i++){ scanf("%d%d%d",&o,&x,&y); x--;y--;a[x][y]=o; if (o){ scanf("%d%d",&u,&v); u--;v--;a[u][v]=o; b[x][y][0]=1<<u;b[x][y][1]=1<<v; b[u][v][0]=1<<x;b[u][v][1]=1<<y; } } f[0]=1; printf("%d\n",F(k-1,k-1)); return 0; }
标签:wedge,洛谷,一组,int,s2,s1,P4547,15,THUWC2017 来源: https://www.cnblogs.com/xjqxjq/p/12343276.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。