ZJNU 1710 dfs

本文介绍了一道关于比萨配料组合的问题,通过使用递归深度优先搜索算法来解决配料组合的计算难题。针对特定数量的配料及它们之间的相容限制,文章详细解释了如何运用二进制位操作来高效地找出所有可能的组合。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

GEPPETTO
Time Limit: 500MS Memory Limit: 65536K


Description

Everyone’s favorite character and puppet-maker Geppetto has opened a new pizza place, the best in town. Geppetto is trying to make the best pizza possible, but at the same time he doesn’t want to have a small selection of pizzas. He makes his pizzas out of N ingredients marked with numbers from 1 to N. All that would be simple if he could mix any ingredient with every ingredient on the pizza, but unfortunately, that is not the case. Sometimes some ingredients cannot mix and that creates additional complications for our pizza master. There are M pairs of ingredients that cannot be on the same pizza at the same time. Given these restrictions, Geppetto wants to know how many different pizzas he can make. Help him answer this question. Two pizzas are considered different if there is an ingredient of index i that is on one pizza, but not on the other.

Input

The first line of input contains two integers N and M (1 <= N <= 20, 1 <= M <= 400). Each of the following M lines contains two different numbers a i b, they represent the prohibition of mixing ingredients marked with a and b on the pizza. (1 <= a, b <= N). All pairs of ingredients are not necessarily distinct, some pair could occur multiple times.

Output

The first and only line of output must contain the number of different pizzas given the restrictions in the task

Sample Input

3 2
1 2
2 3

3 0 

3 3
1 2
1 3
2 3

Sample Output

5
8
4



题意就是给你n种调料,m种限制,就是a调料和b调料不能放一起,现在问你有几种加调料的方法,当然也可以不加。
纠结了很久的一道题 ,通过不断地问学长才理解了,搜索真心强大!



#include<iostream>
using namespace std;
int i,n,m,a,b,cannot[20];//调料编号为0-19
int dfs(int x,int sum){    //用2进制的0与1代表当前位的放调料与不放调料
	if(x==n)return 1;      // 如果搜索到了第n+1种调料,返回1。
	if(!(cannot[x]&sum))return dfs(x+1,sum|(1<<x))+dfs(x+1,sum);
//如果当前的配料与已知不冲突的话,则搜索放这种调料与不放这种调料的两种情况。
	else return dfs(x+1,sum);//否则只能搜索不放这种调料的情况。
}
int main(){
	cin>>n>>m;	
	for(i=0;i<m;i++){
		cin>>a>>b;
		a--;
		b--;
		cannot[a]|=(1<<b);数组a的二进制或上b,直接判断
		cannot[b]|=(1<<a);同理
	}
	cout<<dfs(0,0)<<endl;从不放调料开始搜,直到所有情况都搜索完
	return 0;	
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值