I - Nice to Meet You
Posted achenchen
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了I - Nice to Meet You相关的知识,希望对你有一定的参考价值。
和10-17 B 君的第三题 类似,应该算是简化版,给出了固定的点。
f[s]表示只考虑连端都在s集合中的边,s中的固定点(1或者2)能到达整个集合的方案数。
预处理c[s]表示s集合中的总边数,转移就用所有方案减去s集合中有一部分不能到达的方案,也就是枚举一个子集作为能到达的,这个子集的补集和子集之间的边方向确定了,补集内的边随便选,也就和无向图每条边选或者不选等价了。
和无向图不同的是,1能到达的点的集合为s1,2能到达的点的集合为s2的时候,(s1,s2的补集内的边随便定向,补集和s1,s2之间的边方向唯一确定),s1中的任意点不能于s2中的点有连边,因为一个点x不在s2中表明它到s2集合内的点的边都是指向s2的,那么x若在s1中,s1和s2就联通了。
一开始一直wa三个点,因为我固定一个点的时候枚举子集可以为0但是我跳出了。。。
1 //Achen
2 #include<bits/stdc++.h>
3 #define For(i,a,b) for(int i=(a);i<=(b);i++)
4 #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
5 #define Formylove return 0
6 const int N=32777,p=1e9+7;
7 typedef long long LL;
8 typedef double db;
9 using namespace std;
10 int n,m,a[123],b[123],mp[20][20];
11 LL pr[123],c[N],f[N],to[N];
12 LL ans;
13
14 template<typename T> void read(T &x) {
15 char ch=getchar(); x=0; T f=1;
16 while(ch!=‘-‘&&(ch<‘0‘||ch>‘9‘)) ch=getchar();
17 if(ch==‘-‘) f=-1,ch=getchar();
18 for(;ch>=‘0‘&&ch<=‘9‘;ch=getchar()) x=x*10+ch-‘0‘; x*=f;
19 }
20
21 //#define ANS
22 int main() {
23 #ifdef ANS
24 freopen("1.in","r",stdin);
25 freopen("1.out","w",stdout);
26 #endif
27 read(n); read(m);
28 pr[0]=1;
29 For(i,1,120) pr[i]=2LL*pr[i-1]%p;
30 For(i,1,m) {
31 read(a[i]); read(b[i]);
32 mp[a[i]][b[i]]++;
33 mp[b[i]][a[i]]++;
34 c[pr[a[i]-1]+pr[b[i]-1]]++;
35 }
36 For(i,1,n) {
37 For(j,1,n) if(mp[i][j]) to[pr[i-1]]|=pr[j-1];
38 }
39 int up=pr[n]-1;
40 For(i,0,n-1) For(s,1,up) {
41 if(!(s&pr[i])) {
42 c[s|pr[i]]+=c[s];
43 to[s|pr[i]]|=to[s];
44 }
45 }
46 //For(i,1,up) printf("%d : %d
",i,to[i]);
47 f[1]=f[2]=1;
48 For(s,3,up) {
49 LL t=0;
50 for(int ss=((s-1)&s);ss;ss=((ss-1)&s)) {
51 if((!(s&2)&&(s&1)&&!(ss&2)&&(ss&1))||(!(s&1)&&(s&2)&&!(ss&1)&&(ss&2)))
52 t=(t+f[ss]*pr[c[s^ss]]%p)%p;
53 }
54 if((!(s&2)&&(s&1))||(!(s&1)&&(s&2))) f[s]=(pr[c[s]]-t+p)%p;
55 }
56 For(s,1,up) if((s&1)&&!(s&2)) {
57 int S=(up^s)-2;
58 for(int ss=S;;ss=((ss-1)&S)) {
59 if((s&to[up^s^ss])!=0||((up^s^ss)&to[s])!=0) {
60 if(!ss) break; else continue;
61 }
62 ans=(ans+f[s]*f[up^s^ss]%p*pr[c[ss]]%p)%p;
63 if(!ss) break;
64 }
65 }
66 printf("%lld
",(pr[m]-ans+p)%p);
67 Formylove;
68 }
以上是关于I - Nice to Meet You的主要内容,如果未能解决你的问题,请参考以下文章