• 【BZOJ 4455】 4455: [Zjoi2016]小星星 (容斥原理+树形DP)


    4455: [Zjoi2016]小星星

    Time Limit: 10 Sec  Memory Limit: 512 MB
    Submit: 426  Solved: 255

    Description

    小Y是一个心灵手巧的女孩子,她喜欢手工制作一些小饰品。她有n颗小星星,用m条彩色的细线串了起来,每条细
    线连着两颗小星星。有一天她发现,她的饰品被破坏了,很多细线都被拆掉了。这个饰品只剩下了n?1条细线,但
    通过这些细线,这颗小星星还是被串在一起,也就是这些小星星通过这些细线形成了树。小Y找到了这个饰品的设
    计图纸,她想知道现在饰品中的小星星对应着原来图纸上的哪些小星星。如果现在饰品中两颗小星星有细线相连,
    那么要求对应的小星星原来的图纸上也有细线相连。小Y想知道有多少种可能的对应方式。只有你告诉了她正确的
    答案,她才会把小饰品做为礼物送给你呢。

    Input

    第一行包含个2正整数n,m,表示原来的饰品中小星星的个数和细线的条数。
    接下来m行,每行包含2个正整数u,v,表示原来的饰品中小星星u和v通过细线连了起来。
    这里的小星星从1开始标号。保证u≠v,且每对小星星之间最多只有一条细线相连。
    接下来n-1行,每行包含个2正整数u,v,表示现在的饰品中小星星u和v通过细线连了起来。
    保证这些小星星通过细线可以串在一起。
    n<=17,m<=n*(n-1)/2

    Output

    输出共1行,包含一个整数表示可能的对应方式的数量。
    如果不存在可行的对应方式则输出0。

    Sample Input

    4 3
    1 2
    1 3
    1 4
    4 1
    4 2
    4 3

    Sample Output

    6

    HINT

    Source

     
    【分析】
      很久之前的比赛的一题。【好题啊但是我为什么没有写题解?
      先不考虑每个点一一对应的话,对应关系正确当且仅当树上有的边,对应到原来的无向图上的边也有。
      f[x][i]表示x这个点对应i这个点的情况下,x这棵子树的对应关系正确的方案数。
      这个树形DP即可,n^3。
      但是要保证一一对应,那么可能有一些点没有被对应,所以用容斥。
      枚举没有对应的点,若为奇则减,为偶则加。
      【记得好像不用边目录会T?
      【好像这种“恰好”或者“一一对应”的题目都很经常用容斥,你不能保证要保证的东西,容斥一下就会变得简单
     
      1 #include<cstdio>
      2 #include<cstdlib>
      3 #include<cstring>
      4 #include<iostream>
      5 #include<algorithm>
      6 using namespace std;
      7 #define INF 0xfffffff
      8 #define Maxn 20
      9 #define LL long long
     10 
     11 bool c[Maxn][Maxn];
     12 int fa[Maxn],first[Maxn];
     13 
     14 int n,m;
     15 
     16 struct node
     17 {
     18     int x,y,next;
     19 }t[2*Maxn];int len;
     20 
     21 void ins(int x,int y)
     22 {
     23     t[++len].x=x;t[len].y=y;
     24     t[len].next=first[x];first[x]=len;
     25 }
     26 
     27 void dfs(int x,int f)
     28 {
     29     fa[x]=f;
     30     for(int i=first[x];i;i=t[i].next) if(t[i].y!=f)
     31     {
     32         dfs(t[i].y,x);
     33     }
     34 }
     35 
     36 LL f[Maxn][Maxn];
     37 
     38 void get_f(int x,int s)
     39 {
     40     for(int i=first[x];i;i=t[i].next) if(t[i].y!=fa[x])
     41     {
     42         get_f(t[i].y,s);
     43     }
     44     for(int i=1;i<=n;i++) if(((1<<i-1)&s)==0)
     45     {
     46         f[x][i]=1;
     47         for(int j=first[x];j;j=t[j].next) if(t[j].y!=fa[x])
     48         {
     49             LL now=0;
     50             int y=t[j].y;
     51             for(int k=1;k<=n;k++) if(c[i][k])
     52             {
     53                 now+=f[y][k];
     54             }
     55             f[x][i]*=now;
     56         }
     57     }
     58     else f[x][i]=0;
     59 }
     60 
     61 int main()
     62 {
     63     memset(c,0,sizeof(c));
     64     scanf("%d%d",&n,&m);
     65     for(int i=1;i<=m;i++)
     66     {
     67         int x,y;
     68         scanf("%d%d",&x,&y);
     69         c[x][y]=c[y][x]=1;
     70     }
     71     memset(first,0,sizeof(first));
     72     for(int i=1;i<n;i++)
     73     {
     74         int x,y;
     75         scanf("%d%d",&x,&y);
     76         ins(x,y);ins(y,x);
     77     }
     78     dfs(1,0);
     79     int mx=(1<<n)-1;
     80     LL ans=0;
     81     for(int i=1;i<=mx;i++)
     82     {
     83         // memset(f,0,sizeof(f));
     84         get_f(1,i);
     85         int h=0,now=i;
     86         LL sum=0;
     87         while(now)
     88         {
     89             if(now&1) h++;
     90             now/=2;
     91         }
     92         for(int j=1;j<=n;j++) sum+=f[1][j];
     93         if(h%2==0) ans+=sum;
     94         else ans-=sum;
     95     }
     96     // memset(f,0,sizeof(f));
     97     get_f(1,0);
     98     for(int j=1;j<=n;j++) ans+=f[1][j];
     99     printf("%lld
    ",ans);
    100     return 0;
    101 }
    View Code

    2017-04-20 17:23:11

  • 相关阅读:
    Excel的Range对象(C#)
    SQLServer中常用的一些操作表,字段和索引的SQL语句
    C#和Java初始化顺序
    Raid创建
    转WPF的Presenter(ContentPresenter)
    oracle 开机启动
    LVM介绍以及使用
    Web Service 返回参数
    ControlTemplate & DataTemplate
    设置SSH信任
  • 原文地址:https://www.cnblogs.com/Konjakmoyu/p/6739856.html
Copyright © 2020-2023  润新知