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

hdu5305 Friends(dfs+map/hash)

时间:2015-07-23 23:46:12      阅读:189      评论:0      收藏:0      [点我收藏+]

标签:dfs   hash   map   二进制枚举   

题目:http://acm.hdu.edu.cn/showproblem.php?pid=5305

题意:给定N个人和M条朋友关系,是朋友关系的两个人之间有两种联系方式online和offline。使每个人的online的数量和offline的数量相等,求方案数。

分析:由于M<=28,暴力枚举的话2^28很大,会超时。可以考虑把所有的状态平分成两半,即枚举前面M/2条关系,暴力求出前面的2^(M/2)种状态,然后枚举后面M/2条关系,暴力求出后面2^(M/2)种状态,再枚举后面一半的状态,对于每一种状态直接在前面一半的状态里面找出满足条件的即可。找状态用dfs比二进制枚举要快,查询的话map比hash方便。。。

代码:

#include <iostream>
#include <vector>
#include <cstdio>
#include <cstring>
#include <map>
using namespace std;
int N,M,cnt[20],buf[20],f[20],ans,tp;
struct node
{
	int a,b;
}e[200];
map <vector<int>,int> mp;
void dfs(int x,int y)
{
	if(x>y)
	{
		if(tp==1)
			mp[vector <int> (buf+1,buf+N+1)]++;
		else
		{
			for(int i=1;i<=N;i++)
				f[i]=(cnt[i]>>1)-buf[i];
			if(mp.find(vector <int> (f+1,f+N+1))!=mp.end())
				ans+=mp[vector <int> (f+1,f+N+1)];
		}
		return ;
	}
	buf[e[x].a]++;
	buf[e[x].b]++;
	if(buf[e[x].a]<=(cnt[e[x].a]>>1) && buf[e[x].b]<=(cnt[e[x].b]>>1))
		dfs(x+1,y);
	buf[e[x].a]--;
	buf[e[x].b]--;
	
	dfs(x+1,y);
}
int main()
{
	int ncase,i,j,z;
	scanf("%d",&ncase);
	while(ncase--)
	{
		scanf("%d%d",&N,&M);
		mp.clear();
		memset(cnt,0,sizeof(cnt));
		ans=0;
		for(i=1;i<=M;i++)
		{
			scanf("%d%d",&e[i].a,&e[i].b);
			cnt[e[i].a]++;
			cnt[e[i].b]++;
		}
		z=1;
		for(i=1;i<=N;i++)
			if(cnt[i]&1)
				z=0;
		if(!z)
		{
			printf("0\n");
			continue ;
		}
		tp=1;
		dfs(1,M/2);
		tp=2;
		dfs(M/2+1,M);
		printf("%d\n",ans);
	}
	return 0;
}


版权声明:本文为博主原创文章,未经博主允许不得转载。

hdu5305 Friends(dfs+map/hash)

标签:dfs   hash   map   二进制枚举   

原文地址:http://blog.csdn.net/w20810/article/details/47030255

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