hdu 3091 Necklace(状态压缩类似于TSP问题)

Necklace

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 327680/327680 K (Java/Others)
Total Submission(s): 709    Accepted Submission(s): 245


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
 

 

Source
 
/*
	已经给了时间看题解了,正式练习一道题三天之内不准再看题解!
*/
#include<iostream>
#include<string.h>
#include<stdio.h>
#define N (1<<18)+5
#define M 20
#define INF 0x3f3f3f3f
using namespace std;
long long dp[N][M],g[M][M],n,m;//dp[i][j]表示在i个状态下,你到达j这个点的方案数
int main()
{
	//freopen("in.txt", "r", stdin);
	while(scanf("%lld%lld",&n,&m)!=EOF)
	{
		memset(dp,0,sizeof dp);
		memset(g,0,sizeof g);
		int a,b;
		for(int i=0;i<m;i++)
		{
			scanf("%lld%lld",&a,&b);
			g[a-1][b-1]=g[b-1][a-1]=1;
		}
		int tol=(1<<n);
		dp[1][0]=1;
		for(int i=1;i<tol;i++)
		{
			for(int j=0;j<n;j++)//枚举你要经过的中间点
			{
				if(dp[i][j]==0) continue;//上一个状态没有方案数的讨论没意义
				//cout<<"ok"<<endl;
				for(int k=1;k<n;k++)//枚举你这个状态最终要到达的终点
				{
					if(!(i&(1<<k))&&g[j][k])
					{
						//cout<<"ok"<<endl;
						dp[i|(1<<k)][k]+=dp[i][j];
					}	
				}
			}
		}
		long long s=0;
		for(int i=0;i<n;i++)
		{
			//cout<<dp[tol-1][i]<<" ";
			if(g[0][i])
				s+=dp[tol-1][i];
		}
		//cout<<endl;
		printf("%lld\n",s);
	}
	return 0;
}

  

 
posted @ 2016-08-05 19:39  勿忘初心0924  阅读(315)  评论(0编辑  收藏  举报