题目链接:​​http://acm.hdu.edu.cn/showproblem.php?pid=3091​

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 327680/327680 K (Java/Others)


Problem Description


One day , Partychen gets several beads , he wants to make these beads a necklace . But not every beads can link to each other, every bead should link to some particular bead(s). Now , Partychen wants to know how many kinds of necklace he can make.


 


Input


It consists of multi-case .

Every case start with two integers N,M ( 1<=N<=18,M<=N*N )

The followed M lines contains two integers a,b ( 1<=a,b<=N ) which means the ath bead and the bth bead are able to be linked.


 


Output


An integer , which means the number of kinds that the necklace could be.


 


Sample Input



3 3


1 2


1 3


2 3


 


Sample Output



2


 

题意:

给你N个珠子,这些珠子编号为1~N,然后给出可以连在一起的两个珠子的编号,求把他们全部串起来有多少种方案。

样例有两种项链穿法:

  ①:“1-2-3-1”(包含“2-3-1-2”,“3-1-2-3”这两种情况);

  ②:“1-3-2-1”(包含“3-2-1-3”,“2-1-3-2”这两种情况);

可以看出,珠子串出的项链呈环状,但是珠子有规定好的逆时针或者顺时针的顺序,不能翻面;

 

题解:

设 i 表示状态:i转化为二进制数后,第k位(从右往左数)为0,表示k号珠子还没穿上去;为1,就代表已经穿上去了;

设 j 代表当前状态下,最后一个穿上去的是j号珠子;

设dp[i][j]表示在(i,j)状态下的方案数;

 

AC代码:



1 #include<cstdio>
2 #include<cstring>
3 #include<vector>
4 using namespace std;
5 typedef long long ll;
6 int n,m;
7 bool link[20][20];
8 ll dp[1<<18][20],ans;
9 int main()
10 {
11 while(scanf("%d%d",&n,&m)!=EOF)
12 {
13 memset(link,0,sizeof(link));
14 memset(dp,0,sizeof(dp));
15 for(int i=1,u,v;i<=m;i++)
16 {
17 scanf("%d%d",&u,&v);
18 link[v][u]=link[u][v]=1;
19 }
20
21 int ed_state=(1<<n)-1;
22 dp[1][1]=1;
23 for(int state=1;state<=ed_state;state++)
24 {
25 for(int i=1;i<=n;i++)
26 {
27 if( (state&(1<<(i-1)))==0 || dp[state][i]==0 ) continue;
28 for(int j=1;j<=n;j++)
29 {
30 if(!link[i][j]) continue;//这两颗珠子不能连在一起,跳过
31 if( state & (1<<(j-1)) ) continue;//这颗珠子已经在项链上,跳过
32 int next_state=state|(1<<(j-1));
33 dp[next_state][j]+=dp[state][i];
34 //printf("dp[%d][%d]=%I64d\n",next_state,next_bead,dp[next_state][next_bead]);
35 }
36 }
37 }
38
39 ans=0;
40 for(int i=1;i<=n;i++) if(link[i][1]) ans+=dp[ed_state][i];
41 printf("%I64d\n",ans);
42 }
43 }