• 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
    ");
    			continue ;
    		}
    		tp=1;
    		dfs(1,M/2);
    		tp=2;
    		dfs(M/2+1,M);
    		printf("%d
    ",ans);
    	}
    	return 0;
    }

    另一种更简单的方法,直接dfs然后剪一下枝。假设一个人有x个朋友,那么暴力搜的过程中出现online的个数>x/2或者offline的个数>x/2就不满足条件也就不用搜了。

    #include <iostream>
    #include <cstdio>
    using namespace std;
    
    int on[10],off[10],d[10],N,M,ans,x[30],y[30];
    void dfs(int cur)
    {
    	if(cur>M)
    	{
    		for(int i=1;i<=N;i++)
    			if(on[i]!=off[i])
    				return ;
    		++ans;
    		return ;
    	}
    	int u=x[cur],v=y[cur];
    	if(on[u]<d[u]/2 && on[v]<d[v]/2)
    	{
    		on[u]++;on[v]++;
    		dfs(cur+1);
    		on[u]--;on[v]--;
    	}
    	if(off[u]<d[u]/2 && off[v]<d[v]/2)
    	{
    		off[u]++;off[v]++;
    		dfs(cur+1);
    		off[u]--;off[v]--;
    	}
    }
    int main()
    {
    	int ncase,i,j,k;
    	scanf("%d",&ncase);
    	while(ncase--)
    	{
    		scanf("%d%d",&N,&M);
    		memset(d,0,sizeof(d));
    		for(i=1;i<=M;i++)
    		{
    			scanf("%d%d",&x[i],&y[i]);
    			d[x[i]]++;
    			d[y[i]]++;
    		}
    		ans=0;
    		dfs(1);
    		printf("%d
    ",ans);
    	}
    	return 0;
    }


  • 相关阅读:
    Django实现表单验证、CSRF、cookie和session、缓存、数据库多表操作(双下划綫)
    c3p0连接池封装
    关于springboot
    Maven工程
    Servlet 的面试题
    Servlet request 面试题
    spring MVC 核心配置
    日志配置
    mybatis的核心配置文件
    mapper的配置文件
  • 原文地址:https://www.cnblogs.com/claireyuancy/p/6946462.html
Copyright © 2020-2023  润新知