【BZOJ 4013】[HNOI2015]实验比较
来源:互联网 发布:软件进口代理 编辑:程序博客网 时间:2024/06/06 19:03
题目描述
BZOJ4013—Portal
题目解析
首先我们把每个数看做一个点,不妨将等号连接的两个点缩点,然后剩下的约束关系便会形成一棵树或森林(至于为什么是一棵树请看题目—哭,这是道语文题吧,写那么小),我们要求的合法序列中的等号两端也可以缩成一个块,因为等号两端无论怎么交换也不会产生新的方案,那么现在题目就变成了对于一棵树,求有多少种排列方案保证父节点在序列中排在子节点前。对于一颗子树,我们设以
代码
/************************************************************** Problem: 4013 User: bzjudge2 Language: C++ Result: Accepted Time:36 ms Memory:1440 kb****************************************************************/#include<iostream>#include<cstring>#include<cstdio>#include<cmath>#include<algorithm>#include<cstdlib>using namespace std;#define MAXN 100#define MAXM 100#define INF 0x3f3f3f3ftypedef long long int LL;const int MOD = 1e9+7;template<class T>void Read(T &x){ x=0;char c=getchar();bool flag=0; while(c<'0'||'9'<c){if(c=='-')flag=1;c=getchar();} while('0'<=c&&c<='9'){x=x*10+c-'0';c=getchar();} if(flag)x=-x;}struct node{ int v; node *nxt;}*adj[MAXN+10],Edges[MAXM*2+10],*New=Edges;void addedge(int u,int v){ node *p=++New; p->v=v; p->nxt=adj[u]; adj[u]=p;}int n,m;int u[MAXM+10],v[MAXM+10];int d[MAXN+10];int rt[MAXN+10];int root(int x){return rt[x]=(rt[x]==x?x:root(rt[x]));}int C[MAXN+10][MAXN+10];void init(){ C[0][0]=1; for(int i=1;i<=n;++i){ C[i][0]=C[i][i]=1; for(int j=1;j<i;++j) C[i][j]=(C[i-1][j-1]+C[i-1][j])%MOD; } for(int i=1;i<=n;++i)rt[i]=i;}LL dp[MAXN+10][MAXN+10];LL g[MAXN+10];int sz[MAXN+10];bool vis[MAXN+10];bool dfs(int x){ vis[x]=true; bool fir=true; for(node *p=adj[x];p!=NULL;p=p->nxt){ if(vis[p->v])return false; if(!dfs(p->v))return false; if(fir){ sz[x]=sz[p->v],fir=false; for(int i=1;i<=sz[x];++i)dp[x][i]=dp[p->v][i]; } else{ memset(g,0,sizeof(g)); for(int j=1;j<=sz[x];++j) for(int k=1;k<=sz[p->v];++k)if(dp[x][j]&&dp[p->v][k]) for(int i=max(j,k);i<=j+k;++i) g[i]=(g[i]+dp[x][j]*dp[p->v][k]%MOD*C[i][j]%MOD*C[j][k-(i-j)]%MOD)%MOD; sz[x]+=sz[p->v]; for(int i=1;i<=sz[x];++i)dp[x][i]=g[i]; } } if(x){ ++sz[x]; if(!fir)for(int i=sz[x];i>=1;--i)dp[x][i]=dp[x][i-1]; else dp[x][1]=1; } return true;}int main(){ Read(n),Read(m); init(); int a,b; char str[3]; int cnt=0; for(int i=1;i<=m;++i){ scanf("%d%s%d",&a,str,&b); if(str[0]=='=')rt[root(a)]=root(b); else u[++cnt]=a,v[cnt]=b; } for(int i=1;i<=cnt;++i){ a=root(u[i]),b=root(v[i]); if(a==b){ puts("0"); return 0; } else addedge(a,b),++d[b]; } for(int i=1;i<=n;++i){ a=root(i); if(!d[a])addedge(0,a),++d[a]; } if(!dfs(0)){ puts("0"); return 0; } else{ LL ans=0; for(int i=1;i<=sz[0];++i) ans=(ans+dp[0][i])%MOD; printf("%lld\n",ans); }}
0 0
- BZOJ 4013: [HNOI2015]实验比较
- 【BZOJ 4013】[HNOI2015]实验比较
- BZOJ 4013: [HNOI2015]实验比较
- [树形DP] BZOJ 4013 [HNOI2015]实验比较
- 4013: [HNOI2015]实验比较
- BZOJ 4013 HNOI2015 实验比较 树形DP+组合数学
- bzoj 4013: [HNOI2015]实验比较 (树形DP+组合数学)
- bzoj 4013: [HNOI2015]实验比较 树形dp+排列组合
- bzoj4013: [HNOI2015]实验比较
- bzoj4013: [HNOI2015]实验比较
- BZOJ4013: [HNOI2015]实验比较
- 【bzoj4013】[HNOI2015]实验比较 树形dp+组合数学
- BZOJ 4011: [HNOI2015]落忆枫音
- 【BZOJ 4011】 [HNOI2015]落忆枫音
- BZOJ 4011 HNOI2015 落忆枫音
- BZOJ 4011: [HNOI2015]落忆枫音
- BZOJ 4012: [HNOI2015]开店
- BZOJ 4011 [HNOI2015]落忆枫音
- IE9中table中出现空白单元格的解决办法
- 遥远
- Nginx反向代理实现会话(session)保持的两种方式
- Android6.0运行时权限原生实现和MIUI下的处理
- caffe 使用自己的数据集训练faster-rcnn
- 【BZOJ 4013】[HNOI2015]实验比较
- doGet和doPst的区别
- [转]ARM Compiler 6编译error'#pragma push/pop' is an ARM Compiler 5
- flex弹性布局
- NOR flash 和NAND flash区别深入分析
- 《C和指针》——声明数组参数
- Android 沉浸式
- iOS模仿安卓Material Design的涟漪动画按钮
- 历届试题 九宫重排 (bfs 康托判重)