• 题解CF11D A Simple Task


    题目:CF11D A Simple Task

    状压!但是细节很多,不注意会TWAT
    1.为了方便编号从0开始,所以链式前向星必须把h[i]置为-1
    2.当(s&-s)>(1<<j)时,即选择的点集合中最小的一个点都比j大时,要continue!!!因为这时s&(1<<j)==0,但是它并不能累加贡献和转移!!!因为这里没考虑到疯狂WA……
    3.只有s中包含j而且s的最后一个选择的点恰好是j的时候累加贡献。
    4.不开long long 见祖宗
     1 #include<stdio.h>
     2 #define it register int
     3 #define il inline
     4 const int N=1000005;
     5 int n,m,h[N],nxt[N],adj[N],t,u,v,lim;
     6 long long ans,f[20][N];
     7 il void add(){
     8     nxt[++t]=h[u],h[u]=t,adj[t]=v,nxt[++t]=h[v],h[v]=t,adj[t]=u;
     9 }
    10 il void fr(int &num){
    11     num=0;char c=getchar();int p=1;
    12     while(c<'0'||c>'9') c=='-'?p=-1,c=getchar():c=getchar();
    13     while(c>='0'&&c<='9') num=num*10+c-'0',c=getchar();
    14     num*=p;
    15 }  
    16 int main(){
    17     fr(n),fr(m),lim=1<<n; 
    18     for(it i=0;i<n;++i) f[i][1<<i]=1,h[i]=-1;
    19     for(it i=1;i<=m;++i) fr(u),fr(v),--u,--v,add();
    20     for(it s=1;s<lim;++s)
    21         for(it i=0;i<n;++i)
    22             if(f[i][s])
    23                 for(it tp=h[i],j;~tp;tp=nxt[tp]){
    24                     j=adj[tp];
    25                     if((s&-s)>(1<<j)) continue;
    26                     if((s&(1<<j))) ans+=((s&-s)==(1<<j)?f[i][s]:0);
    27                     else f[j][s|(1<<j)]+=f[i][s]; 
    28                 }
    29     printf("%lld",ans-m>>1);
    30     return 0;
    31 }
    View Code
  • 相关阅读:
    蓝桥杯_基础训练_龟兔赛跑预测
    大数加法
    Splay!
    topsort
    各种方法
    有时候dfs可以简化各种组合的操作
    组合数学
    重新认识三观
    手速狗还是不行啊。。。
    set和map和pair 转自ACdreamers
  • 原文地址:https://www.cnblogs.com/Kylin-xy/p/11753075.html
Copyright © 2020-2023  润新知