• I


    传送门

    和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 }
    View Code
  • 相关阅读:
    GyPSii API PHP应用初探
    无缝滚动图片的一个简单封装
    Linux设置固定IP
    DIV卷帘效果示例
    vsftp安装配置
    PHP判断FORM来的数据是否为整数
    Linux下设置apache开机启动
    从Discuz提取的数据库和模板操作文件,很容易使用哦
    discuz 表情的提取
    IE6、IE7浮动层被下面的动挡住的问题
  • 原文地址:https://www.cnblogs.com/Achenchen/p/9835384.html
Copyright © 2020-2023  润新知