码迷,mamicode.com
首页 > 其他好文 > 详细

多校5 hdu4917

时间:2014-08-08 15:56:16      阅读:328      评论:0      收藏:0      [点我收藏+]

标签:des   style   blog   http   color   java   os   io   

Permutation

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 365    Accepted Submission(s): 98


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.
 

 

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).
 

 

Output
For each tests:

A single number denotes the number of permutations.
 

 

Sample Input
3 1
1 2
3 2
1 2
2 3
 

 

Sample Output
3
1
 

 

Author
Xiaoxu Guo (ftiasch)
 
 
 

 

 
求得每个连通子图的拓扑排序的数量,在乘上相应的组合数
两种方式进行状压效果都是一样的,不过bfs感觉比较好理解。
都是从已经结束的状态转移到新的状态。
 
 
bubuko.com,布布扣
  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <queue>
  5 
  6 using namespace std;
  7 
  8 typedef long long LL;
  9 const LL N=43;
 10 LL fa[N];
 11 LL n,m;
 12 LL fin(LL x){return x==fa[x]?x:fa[x]=fin(fa[x]);}
 13 LL _a[N];
 14 LL _b[N];
 15 LL d[1<<21];
 16 LL cen[N];
 17 LL C[N][N];
 18 LL vis[N];
 19 LL new_id[N];
 20 const LL mod=1e9+7;
 21 LL q[1<<21+1];
 22 LL head,tail;
 23 int inq[1<<21];
 24 void updata(LL &a,LL b){
 25     a=a+b;
 26     if(a>=mod)a-=mod;
 27 }
 28 LL solve(LL nn){
 29 
 30     head=tail=0;
 31     q[tail++]=0;
 32     memset(d,0,sizeof(LL)*(1<<nn));
 33     d[0]=1;
 34     inq[0]=1;
 35     memset(inq,0,sizeof(int)*(1<<nn));
 36     while(head<tail){
 37         LL u=q[head++];
 38 
 39         for(LL i=0;i<nn;i++)if((u&(1<<i))==0&&(u|cen[i])==u){
 40             updata(d[u|(1<<i)],d[u]);
 41             if(!inq[u|(1<<i)]){
 42                 q[tail++]=u|(1<<i);
 43                 inq[u|(1<<i)]=1;
 44             }
 45         }
 46     }
 47     return d[(1<<nn)-1];
 48 }
 49 
 50 /*LL solve(LL nn){
 51     memset(d,0,sizeof(LL)*(1<<nn));
 52     d[0]=1;
 53     for(LL u=0;u<(1<<nn);u++){
 54         for(LL i=0;i<nn;i++)if((u&(1<<i))==0&&(u|cen[i])==u){
 55             updata(d[u|(1<<i)],d[u]);
 56         }
 57     }
 58     return d[(1<<nn)-1];
 59 }*/
 60 void cal(){
 61     //c(n,m)=c(n-1,m-1)+c(n-1,m);
 62     for (int i = 0; i < N; ++ i) {
 63         C[i][0] = 1;
 64         for (int j = 1; j <= i; ++ j) {
 65             C[i][j] = (C[i - 1][j - 1] + C[i - 1][j]) % mod;
 66         }
 67     }
 68 }
 69 int main()
 70 {
 71 
 72     cal();
 73     while(scanf("%I64d%I64d",&n,&m)!=EOF){
 74 
 75         memset(vis,0,sizeof(vis));
 76 
 77         for(LL i=0;i<=n;i++)fa[i]=i;
 78         for(LL i=0;i<m;i++){
 79             scanf("%I64d%I64d",_a+i,_b+i);
 80             --_a[i];--_b[i];
 81             if(fin(_a[i])!=fin(_b[i])){
 82                 fa[fin(_a[i])]=fin(_b[i]);
 83             }
 84         }
 85 
 86         LL num=n,ret=1;
 87         for(LL i=0;i<n;i++)if(!vis[i]){
 88             LL _id=0;
 89             for(LL j=0;j<n;j++){
 90                 if(fin(i)==fin(j)){
 91                     vis[j]=1;
 92                     new_id[j]=_id++;
 93                 }
 94             }
 95             ret=ret*C[num][_id]%mod;
 96             num-=_id;
 97             memset(cen,0,sizeof(cen));
 98             for(LL j=0;j<n;j++){//预处理每个状态其所有祖先,像贝尔曼一样松弛
 99                 for(LL k=0;k<m;k++)if(fin(i)==fin(_a[k])){
100                     cen[new_id[_b[k]]]|=cen[new_id[_a[k]]]|(1<<new_id[_a[k]]);
101                 }
102             }
103             ret=ret*solve(_id)%mod;
104         }
105         cout<<ret<<endl;
106     }
107     return 0;
108 }
View Code

 

 

多校5 hdu4917,布布扣,bubuko.com

多校5 hdu4917

标签:des   style   blog   http   color   java   os   io   

原文地址:http://www.cnblogs.com/youyouyou/p/3899356.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!