hdu5305 Friends(dfs+map/hash)

题目: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;
}

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

时间: 2024-12-08 01:05:16

hdu5305 Friends(dfs+map/hash)的相关文章

poj 3320 Jessica&#39;s Reading Problem(尺取法+map/hash)

题目:http://poj.org/problem?id=3320 题意:给定N个元素的数组,找出最短的一段区间使得区间里面的元素种类等于整个数组的元素种类. 分析:暴力枚举区间的起点x,然后找到最小的y,使得区间[x,y]满足条件,x向有移位后变成x',现在的y'肯定不至于在y的左边.存状态的话map和hash都可以. map代码: #include <iostream> #include <set> #include <map> #include <cstdi

百度之星D map+hash

Problem D Accepts: 2806 Submissions: 8458 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Problem Description 度熊所居住的 D 国,是一个完全尊重人权的国度.以至于这个国家的所有人命名自己的名字都非常奇怪.一个人的名字由若干个字符组成,同样的,这些字符的全排列的结果中的每一个字符串,也都是这个人的名字.例如,如果一个人名字

hdu - 4403 - A very hard Aoshu problem(dp + dfs + map + 乘法原理)

题意:给出一串数字字符(长度在[2, 15]),现要在其中加一个 "=",不加或加一些 "+",问成立的等式有多少条? 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4403 -->>数据量较小,暴力吧.. 1.dp预处理出任意两个字符间的数值大小 2.枚举 = 的位置,分别对 = 的左边.右边各dfs一次,并记录各个数出现的次数 3.根据乘法原理求组合数 #include <cstdio> #

【BZOJ-3578】GTY的人类基因组计划2 set + map + Hash 乱搞

3578: GTY的人类基因组计划2 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 367  Solved: 159[Submit][Status][Discuss] Description GTY召唤了n个人来做实验,GTY家的房子很大,有m个房间一开始所有人都在1号房间里,GTY会命令某人去某个房间等待做实验,或者命令一段区间的房间开始实验,实验会获得一些实验信息点数,点数为房间里的人数,如果一个房间里的一群人已经做过实验了那么这些人将不会增

POJ 1840 Eqs 二分+map/hash

Description Consider equations having the following form: a1x13+ a2x23+ a3x33+ a4x43+ a5x53=0 The coefficients are given integers from the interval [-50,50]. It is consider a solution a system (x1, x2, x3, x4, x5) that verifies the equation, xi∈[-50,

[JSOI2017]原力(分块+map(hash))

题目描述 一个原力网络可以看成是一个可能存在重边但没有自环的无向图.每条边有一种属性和一个权值.属性可能是R.G.B三种当中的一种,代表这条边上 原力的类型.权值是一个正整数,代表这条边上的原力强度.原力技术的核心在于将R.G.B三种不同的原力融合在一起产生单一的.便于利用的原力.为了评估 一个能源网络,JYY需要找到所有满足要求的三元环(首尾相接的三条边),其中R.G.B三种边各一条.一个三元环产生的能量是其中三条边的权值之积. 现在对于给出的原力网络,JYY想知道这个网络的总能量是多少.网络

1034 Head of a Gang (边不重复 dfs+map)

One way that the police finds the head of a gang is to check people's phone calls. If there is a phone call between A and B, we say that A and B is related. The weight of a relation is defined to be the total time length of all the phone calls made b

URAL 1890 . Money out of Thin Air (dfs序hash + 线段树)

题目链接: URAL 1890 . Money out of Thin Air 题目描述: 给出一个公司里面上司和下级的附属关系,还有每一个人的工资,然后有两种询问: 1:employee x y z ,如果编号为x的员工如果工资小于y,就给他加薪z. 2:department x y z ,如果编号为x的员工所管辖的范围内(包括自己),所有员工的工资平均数小于y,给该范围加薪z. 问q次操作后这个公司内每个员工的工资为多少? 解题思路: 根据上司和下级的附属关系,可以先建一个有向图,然后对有向

hdu5305 Friends(dfs,多校题)

Friends Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 2945    Accepted Submission(s): 1413 Problem Description There are n people and m pairs of friends. For every pair of friends, they can ch