zoukankan      html  css  js  c++  java
  • 题解CF906C Party

    题目:CF906C Party

    啊,多么美妙的状压dp!我开始还以为是拓扑排序或者广搜之类的。。
    我们用f[s]表示到达状态s可以使用的最小次数。那么f[s|a[i]]=Min(f[s|a[i]],f[s]+1),就是枚举每个人认识的人去更新答案。
    然后怎么记录方案数呢?我们记一下这个状态是由哪个状态和哪个人拼起来更新的就可以了。
     1 #include<stdio.h>
     2 #include<string.h>
     3 #define it register int
     4 #define il inline
     5 using namespace std;
     6 const int N=(1<<22)+5;
     7 int f[N],lst[N],ans[N],n,m,lim,a[N];
     8 il void dfs(it x){
     9     if(lst[x]) dfs(lst[x]);
    10     printf("%d ",ans[x]);
    11 }
    12 il void fr(int &num){
    13     num=0;char c=getchar();int p=1;
    14     while(c<'0'||c>'9') c=='-'?p=-1,c=getchar():c=getchar();
    15     while(c>='0'&&c<='9') num=num*10+c-'0',c=getchar();
    16     num*=p;
    17 }  
    18 int main(){
    19     fr(n),fr(m);
    20     if(m==n*(n-1)/2) return putchar('0'),0;
    21     memset(f,127,sizeof(f)),lim=1<<n;
    22     for(it i=1;i<=n;++i) a[i]=(1<<i-1);
    23     for(it i=1,u,v;i<=m;++i) fr(u),fr(v),a[u]|=(1<<v-1),a[v]|=(1<<u-1);
    24     for(it i=1;i<=n;++i) f[a[i]]=1,ans[a[i]]=i; 
    25     for(it s=0,x;s<lim;++s)
    26         if(f[s]<2139062143)
    27             for(it i=1;i<=n;++i)
    28                 if((s&(1<<i-1))&&f[(x=(s|a[i]))]>f[s]+1)
    29                     f[x]=f[s]+1,ans[x]=i,lst[x]=s;
    30     printf("%d
    ",f[lim-1]);
    31     dfs(lim-1);
    32     return 0;
    33 }
    34 /*
    35 f[s]:到达状态s所需要的最小步数
    36 ans[x]:状态x是由ans[x]这个人更新的
    37 lst[x]:状态x的上一个状态
    38 */
    View Code
  • 相关阅读:
    路径不对 导致FileNotFoundError: [WinError 2] 系统找不到指定的文件, 问题解决办法
    pycharm + selenium + python 提示 Unresolved reference 'webdriver' 解决办法
    highstock实现股票分时
    jquery 源码剖析1
    html 其它标签
    html5 基本内容 摘自W3C
    html总结
    web性能 部分
    linux常用命令 3
    linux常用命令 2
  • 原文地址:https://www.cnblogs.com/Kylin-xy/p/11752409.html
Copyright © 2011-2022 走看看