题目

有\(n\)个现实城市,另有\(n\)个幻想城市

原图中在现实城市存在\(m\)条边,在幻想城市存在\(m-1-n\)条边

一个排列是合法的当且进当显示城市 \(i\) 向幻想城市 \(p_i\) 连边后,图是连通的

求合法的排列数目

\(n \le 20 \ , \ 时限10s\)

题解

  • 如果初始连通块个数\(\gt n+1\)个无解;
  • 考虑这\(n+1\)个连通块,设\(S\)表示已经分配好的连通块集合的合法排列个数
  • 转移时用总的减去不合法的,不合法考虑枚举编号最小的城市所在联通块
  • 时间复杂度:\(O(3^{20})\)
  • 由于一个状态如果不满足现实和幻想的连通块点数和相等就是无用的,可以去掉很多无用状态

Code

#include<bits/stdc++.h>
#define mod 998244353
using namespace std;
const int N=21;
int n,m,n1,n2,tot,f[N],sz[N],sz1[1<<N],sz2[1<<N],all1,all2,all,fac[N],F[1<<N],G[1<<N];
int find(int x){return f[x]==x?x:f[x]=find(f[x]);}
void dec(int&x,int y){x-=y;if(x<0)x+=mod;}
void uni(int u,int v){
int fu=find(u),fv=find(v);
if(fu==fv)return;
f[fu]=fv;sz[fv]+=sz[fu];
}
int main(){
freopen("milk.in","r",stdin);
freopen("milk.out","w",stdout); scanf("%d%d",&n,&m);
for(int i=fac[0]=1;i<=n;++i)fac[i]=1ll*fac[i-1]*i%mod; for(int i=1;i<=n;++i)f[i]=i,sz[i]=1;
for(int i=1,u,v;i<=m;++i){
scanf("%d%d",&u,&v);
uni(u,v);
}
for(int i=1;i<=n;++i)if(find(i)==i){
sz1[1<<tot++]=sz[i];
}
n1=tot;tot=0;all1=(1<<n1)-1;
for(int i=0;i<n1;++i)
for(int j=0;j<=all1;++j)
if(j>>i&1)sz1[j]+=sz1[j^(1<<i)]; m=n-1-m;
for(int i=1;i<=n;++i)f[i]=i,sz[i]=1;
for(int i=1,u,v;i<=m;++i){
scanf("%d%d",&u,&v);
uni(u,v);
}
for(int i=1;i<=n;++i)if(find(i)==i){
sz2[1<<tot++]=sz[i];
}
n2=tot;tot=0;all2=(1<<n2)-1;
for(int i=0;i<n2;++i)
for(int j=0;j<=all2;++j)
if(j>>i&1)sz2[j]+=sz2[j^(1<<i)]; all=(1<<(n1+n2))-1;
if(n1+n2!=n+1){puts("0");return 0;}
F[0]=G[0]=1;
for(int S=1;S<=all;++S){
int v1=sz1[S&all1],v2=sz2[S>>n1];
if(v1!=v2)continue;
G[S]=fac[v1];
}
for(int S=1;S<=all;++S)if(G[S]){
F[S]=G[S];
int x=S&-S,R=S^x;
if(x>all1)continue;
for(int T=R;T;T=(T-1)&R)if(G[T]){
dec(F[S],1ll*G[T]*F[S^T]%mod);
}
}
cout<<F[all]<<endl;
return 0;
}

【JZOJ5739】【20190706】毒奶的更多相关文章

  1. 【JZOJ5738】【20190706】锁屏杀

    题目 $n \le 2000 $ 题解 \(B\)的数字可以对1440取模,对三个图分别进行\(dp\)即可 时间复杂度\(O(n\times 1440 \times 10)\) Code #incl ...

  2. 【JZOJ5740】【20190706】幻想世界

    题目 小 $\omega $ 想要进行烟火表演,她一开始有\(n\)颗彗星和\(n\)颗陨石 如果小 \(\omega\) 有\(i\)颗彗星而没有陨石,那么她会消耗\(i\)颗彗星并得到\(a_i\ ...

  3. 2019-07-06 sql 连续出现次数

    由手机通讯记录界面想到的问题 SELECT CASE WHEN AA.num=1 THEN AA.Tel ELSE AA.Tel+'('+CASt(AA.num AS VARCHAR(4))+')' ...

  4. 2019-07-06 sql备忘 连续取最大

    连续最大: SELECT M.* FROM #temp MINNER JOIN (SELECT ISNULL(A.score,0)-b.score AS score,B.id FROM #temp A ...

  5. 论SCRM系统对传统行业的冲击

    SCRM(Social Customer Relationship Management)顾名思义是社会型客户关系管理系统,这在当前的电子商务领域是一个创新的概念,由于社交媒体(Social Medi ...

  6. NOIP2016の遊記

    看了cydiater的游记,我更加认识到我有多弱,大神有多强 剩余的时间不多了,NOIP前停的一周课又颓了相当多的时间,感觉NOIP真的药丸 最后一天复习模板,看一下错误,总结做题的经验,现在实力实在 ...

  7. 【javascript】详解变量,值,类型和宿主对象

    前言 我眼中的<javascript高级程序设计> 和<你不知道的javascript>是这样的:如果<javascript高级程序设计>是本教科书的话, < ...

  8. bzoj4974 字符串大师

    4974: 字符串大师 Time Limit: 1 Sec  Memory Limit: 256 MBSubmit: 310  Solved: 155[Submit][Status][Discuss] ...

  9. PKUWC 2018游记

    PKUWC 2018游记 标签: Day\([-inf,0)\) 停课之后一直各种浪的飞起,考试rank20+,不搞颓但是学习很没有状态.还经常带着耳机被谢总抓了好几次,然后被拉过去谈话了好几次... ...

随机推荐

  1. win10 配置IIS

    互联网信息服务(英語:Internet Information Services),在台湾被称为网际网路资讯服务,是由微软公司提供的基于运行Microsoft Windows的互联网基本服务.最初是W ...

  2. 订单1:n支付单 设计讨论

    方法一:订单1:1支付单,下单时生成1订单,并生成1支付单(这个支付单是微信需要的相关信息),设置超时时间2小时,如果订单超时,则提示用户,订单已超时,重新下单即可: 方法二:订单1:N支付单,下单时 ...

  3. Java : Hibernate 动态+分页+自定义字段+自定义实体类查询

    // 组合查询public List<ListBookDTO> listSetDSL(PublishingHouse publishingHouse,Integer minDiscount ...

  4. [NOI2019] 弹跳

    题意: 给你平面上的$n$个点,共有$m$个弹跳装置. 每个弹跳装置可以从点$p_{i}$以$t_{i}$的代价跳到矩形$(L_{i},D_{i}),(R_{i},U_{i})$中的任何一个点. 现在 ...

  5. 【题解】C2Crni - Crni [COCI2010] [SP7884]

    [题解]C2Crni - Crni [COCI2010] [SP7884] 传送门:\(\text{C2Crni - Crni}\) \(\text{[COCI2010]}\) \(\text{[SP ...

  6. dotnet验证参数

    组长提了一个需求,前端传递过来参数的时候,我们要验证一下参数是否都传递过来了,所以我专门写了一个验证工具类,调用就好了. 第一个参数为 前端传递到Controller封装的实体类,第二个参数为这个实体 ...

  7. 聊聊 .net Core webAPi 的Get和POST 相关(1)

    上篇文章,我们试着调用API,成功返回值,今天接下来看看代码是怎么构成的 [Route("api/[controller]")] [ApiController] public cl ...

  8. layui 动态表格设置单元格样式

    col.push({ field: , templet: function (d) { ") { return '<span style="color:white;backg ...

  9. 线程之间灵活传递信号(ManualResetEventSlim )

    当主程序启动时,首先创建ManualResetEventSlim 类的一个实例.然后启动三个线程,等待事件信号通知它们继续执行. /// <summary> /// 创建 ManualRe ...

  10. 对比ubuntu与centos系统 ​​​​

    CentOS与Ubuntu该如何选择,哪个更好用.笔者在自媒体平台收集了一些网友的观点,较为经典,分享给大家.至于应该选择哪个,希望看完本文章后,读者心中有数. 观点1:CentOS适用于服务器,Ub ...