HDU4917 Permutation(状态压缩dp,图论)
来源:互联网 发布:spss mac使用教程 编辑:程序博客网 时间:2024/06/15 20:06
Permutation
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 896 Accepted Submission(s): 281
Problem Description
bobo has a permutation p1,p2,…,pn of 1,2,…,n.
Knowing m extra constraints of form pai<pbi, bobo wanna count the number of different permutations modulo (109+7).
It is guaranteed that there is at least one such permutation.
Knowing m extra constraints of form pai<pbi, bobo wanna count the number of different permutations modulo (109+7).
It is guaranteed that there is at least one such permutation.
Input
The input consists of several tests. For each tests:
The first line contains n,m (1≤n≤40,0≤m≤20). Each of the following m lines contain 2 integers ai,bi(1≤ai,bi≤n).
The first line contains n,m (1≤n≤40,0≤m≤20). Each of the following m lines contain 2 integers ai,bi(1≤ai,bi≤n).
Output
For each tests:
A single number denotes the number of permutations.
A single number denotes the number of permutations.
Sample Input
3 11 23 21 22 3
Sample Output
31
Author
Xiaoxu Guo (ftiasch)
Source
2014 Multi-University Training Contest 5
题意:一个1-n的排列,给出其中一些数之间的约束条件.问排列的总个数
相当于给出一张图,求拓扑排序的总数是多少.
首先观察数据范围,一共的点不超过40个,一共的边不超过20个,意味着图不一定联通,而且一个连通块中的点最多21个.
我们首先把图分成一个个连通块,依次对每一个联通块处理,一个联通块带来的新的排序树是C(sum,tot)*连通块内拓补排序的总数,sum是剩下的未处理的点的总数.
对于一个连通块内部,用状压dp的方法求出拓扑排序总数.具体的方案是,对于每一个状态i,枚举放到整个拓扑序列的最后一个点,如果点j的前驱都属于i,那么dp[i]+=dp[i&*(~(1<<j))]
#include <map>#include <iostream>#include <algorithm>#include <cstring>#include <cstdio>using namespace std;const int MAXN=50;const long long mod=1e9+7;int d[MAXN][MAXN];int vis[MAXN];int pre[MAXN];int a[MAXN];long long C[MAXN][MAXN];int tot=0;int n,m;void dfs(int s){ int tmp=tot; a[tot++]=s; vis[s]=1; for(int i=1;i<=n;i++){ if(d[s][i]){ if(!vis[i]) dfs(i); if(d[s][i]==1){ for(int j=0;j<tot;j++){ if(a[j]==i){ pre[j]|=(1<<tmp); } } } } }}long long dp[1<<21];long long cal(){ memset(dp,0,sizeof(dp)); dp[0]=1; for(int s=0;s<(1<<tot);s++){ for(int i=0;i<tot;i++){ if(((s&pre[i])==pre[i])&&!(s&(1<<i))) dp[s|(1<<i)]=(dp[s|(1<<i)]+dp[s])%mod; } } return dp[(1<<tot)-1];}int main(){ for(int i=0;i<41;i++){ C[i][0]=1; for(int j=1;j<=i;j++) C[i][j]=(C[i-1][j-1]+C[i-1][j])%mod; } while(scanf("%d%d",&n,&m)!=EOF){ memset(d,0,sizeof(d)); memset(vis,0,sizeof(vis)); for(int i=0;i<m;i++){ int u,v; scanf("%d%d",&u,&v); d[u][v]=1; d[v][u]=-1; } long long x=n; long long ans=1; for(int i=1;i<=n;i++){ if(!vis[i]){ tot=0; memset(pre,0,sizeof(pre)); dfs(i); if(tot<2) ans=(((tot*C[x][tot])%mod)*ans)%mod; else ans=((cal()*C[x][tot])%mod*ans)%mod; x-=tot; } } printf("%lld\n",ans); }}
阅读全文
0 0
- HDU4917 Permutation(状态压缩dp,图论)
- 2014多校5(1007)hdu4917(状态压缩dp+拓扑排序)
- hdu 4917Permutation(状态压缩DP)
- hdu3811 Permutation (状态压缩DP)
- Permutation HUD-3811 (状态压缩)
- 状态压缩dp
- pku1038状态压缩dp
- 状态压缩DP 入门
- HDU1074 状态压缩DP
- Poj3254 状态压缩DP
- 状态压缩DP入门
- 【状态压缩DP】互不侵犯
- 【状态压缩DP】电子竞技
- HDU1074 状态压缩DP
- 【状态压缩DP】互不侵犯
- 状态压缩 DP AHU420
- HDU2167 状态压缩DP
- SGU223 -状态压缩DP
- 最小公倍数 oj56
- Django 使用easy_thumbnails压缩上传的图片
- centos安装mysql5.6
- 【Caffe】利用log文件绘制loss和accuracy(转载)
- Java开发环境搭建
- HDU4917 Permutation(状态压缩dp,图论)
- 取石子游戏 oj57
- fzu 2281 Trades [第八届福建省大学生程序设计竞赛 Problem J Trades] [贪心]
- 支持向量机通俗导论(理解SVM的三层境界)
- list vector set map multimap multiset 容器大揭秘
- QT之海康解码显示小技巧 ~setUpdatesEnabled
- Tomcat系列—服务器安装与配置
- csu1965—Message(斯坦纳树)
- WGS84,GCJ02, BD09坐标转换