[树形DP] BZOJ 4013 [HNOI2015]实验比较
来源:互联网 发布:苹果手机越狱软件 编辑:程序博客网 时间:2024/05/21 03:17
首先缩点 然后肯定会变成一颗森林 不然无解
弄一个超级根
然后
合并的时候
用组合数算一下就好了
#include<cstdio>#include<cstdlib>#include<algorithm>#include<cstring>#define cl(x) memset(x,0,sizeof(x))using namespace std;typedef long long ll;inline char nc(){ static char buf[100000],*p1=buf,*p2=buf; return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;}inline void read(int &x){ char c=nc(),b=1; for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1; for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b;}inline void read(char &x){ for (x=nc();!(x=='>' || x=='<' || x=='=');x=nc());}const int N=105;const int P=1e9+7;ll C[N][N];inline void Pre(int n){ C[0][0]=1; for (int i=1;i<=n;i++){ C[i][0]=1; for (int j=1;j<=n;j++) C[i][j]=(C[i-1][j-1]+C[i-1][j])%P; }}struct edge{ int u,v,next;}G[N<<1];int head[N],inum;inline void add(int u,int v,int p){ G[p].u=u; G[p].v=v; G[p].next=head[u]; head[u]=p;}int vst[N],size[N];ll f[N][N],g[N];#define V G[p].vinline bool dfs(int u){ vst[u]=1; f[u][0]=1; size[u]=0; for (int p=head[u];p;p=G[p].next){ if (vst[V]) return 0; if (!dfs(V)) return 0; cl(g); for (int i=0;i<=size[u];i++) if (f[u][i]) for (int j=0;j<=size[V];j++) if (f[V][j]) for (int k=max(i,j);k<=i+j;k++) g[k]+=f[u][i]*f[V][j]%P*C[k][i]%P*C[i][j-(k-i)]%P; size[u]+=size[V]; for (int i=0;i<=size[u];i++) f[u][i]=g[i]%P; } if (u){ size[u]++; for (int i=size[u];i;i--) f[u][i]=f[u][i-1]; f[u][0]=0; } return 1;}int fat[N];inline int Fat(int u){ return u==fat[u]?u:fat[u]=Fat(fat[u]);}int n,m;int _u[N],_v[N];int deg[N];int main(){ int iu,iv; char c; freopen("t.in","r",stdin); freopen("t.out","w",stdout); read(n); read(m); Pre(n); for (int i=1;i<=n;i++) fat[i]=i; int t=m; m=0; while (t--){ read(iu); read(c); read(iv); if (c=='=') { fat[Fat(iu)]=Fat(iv); continue; } if (c=='>') swap(iu,iv); _u[++m]=iu,_v[m]=iv; } for (int i=1;i<=m;i++){ iu=Fat(_u[i]),iv=Fat(_v[i]); if (iu==iv) return printf("0\n"),0; add(iu,iv,++inum); deg[iv]++; } for (int i=1;i<=n;i++) if (Fat(i)==i && !deg[i]) add(0,i,++inum); if (!dfs(0)) return printf("0\n"),0; ll ans=0; for (int i=1;i<=size[0];i++) ans+=f[0][i]; printf("%d\n",ans%P); return 0;}
0 0
- [树形DP] BZOJ 4013 [HNOI2015]实验比较
- BZOJ 4013 HNOI2015 实验比较 树形DP+组合数学
- bzoj 4013: [HNOI2015]实验比较 (树形DP+组合数学)
- bzoj 4013: [HNOI2015]实验比较 树形dp+排列组合
- BZOJ 4013: [HNOI2015]实验比较
- 【BZOJ 4013】[HNOI2015]实验比较
- BZOJ 4013: [HNOI2015]实验比较
- 【bzoj4013】[HNOI2015]实验比较 树形dp+组合数学
- 4013: [HNOI2015]实验比较
- bzoj4013: [HNOI2015]实验比较
- bzoj4013: [HNOI2015]实验比较
- BZOJ4013: [HNOI2015]实验比较
- BZOJ 4011 HNOI2015 落忆枫音 拓扑序DP
- BZOJ 4008 HNOI2015 亚瑟王 期望DP
- bzoj 4008 [HNOI2015]亚瑟王 期望dp
- [BZOJ 4008][HNOI2015]亚瑟王:期望DP
- BZOJ 2152 (树形DP)
- bzoj 3037(树形DP)
- 与MVC框架解耦的OGNL:前世今生及其基本用法
- LeetCode -- Add Two Numbers
- 2017.4.5所学
- B. Number Busters----数学推演
- Swoole 关于 HTTP SERVER 的事件顺序
- [树形DP] BZOJ 4013 [HNOI2015]实验比较
- RabbitMQ+PHP 消息队列环境配置
- 题目1156:谁是你的潜在朋友 九度OJ
- 冒泡排序,快速排序,归并排序
- Ubuntu 14.04 php7.0 php7.0-fpm nginx 环境搭建备注
- ftp下载命令行工具wget
- Spring集成Quartz有2种方法:
- How to Type
- (七)k-dTree库教程一--k-d树原理介绍