您的位置:首页 > 其它

Hdu 4013 Distinct Subtrees (状态压缩枚举+树的最小表示)

2013-07-17 22:15 316 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4013

题意:一棵由无向边构成的树,求出它的不同的子树的数目。

思路:枚举每个点集,DFS求最小表示。对于某一种情况,若有一次得到的表示以前没有,答案加1。

代码中有一大段被注释掉的部分,那是我最开始的想法,会出现同一棵子树因树根不同而重复记录的情况 。

如果一个点集构成森林,由于遍历了所有组成,所以它的每一棵树都会被遍历到。

本题时间限制5000MS,我的代码跑了4312MS……

#pragma warning(disable:4786)
#include <set>
#include <string>
#include <vector>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;

int n,map[15][15];
bool visit[15];
set<string> s;

string DFS (int u,int pre)
{
	vector<string> v;
	for (int i=0;i<n;i++)
		if (map[u][i] && i!=pre && visit[i])
			v.push_back('0'+DFS(i,u));
	string r;
	sort (v.begin(),v.end());  
	for (int k=0;k<v.size();k++)  
		r+=v[k];  
	return r+'1';  
}

/*错误的处理方式
int Deal ()
{
    int j;
    for (int i=0;i<(1<<n);i++)   //枚举点集
    {
        memset(visit,false,sizeof(visit));
        for (j=0;j<n;j++)
			if (i&(1<<j))
				visit[j]=1;
        for (j=0;j<n;j++)
			if (visit[j])
				s.insert(DFS(j,-1));
    }
    return s.size();
}*/

int Deal ()
{
    int j,ans=0;
    for (int i=0;i<(1<<n);i++)   //枚举点集
    {
		memset(visit,false,sizeof(visit));
		for (j=0;j<n;j++)
			if (i&(1<<j))
				visit[j]=true;
		int flag=0;
		for (j=0;j<n;j++)
			if (visit[j])
			{
				string str=DFS(j,-1);
				if (s.find(str)==s.end())      //见题解
					flag=1,s.insert(str);
			}
		ans+=flag;
	}
	return ans;
}

int main()
{
#ifdef ONLINE_JUDGE
#else
	freopen("read.txt","r",stdin);
#endif
	int T;
	scanf("%d",&T);
	for (int Cas=1;Cas<=T;Cas++)
	{
		s.clear();
		scanf("%d",&n);
		memset(map,0,sizeof(map));
		for (int i=1;i<n;i++)
		{
			int u,v;
			scanf("%d%d",&u,&v);
			map[u-1][v-1]=map[v-1][u-1]=1;
		}
		printf("Case #%d: %d\n",Cas,Deal());
	}
	return 0;
}


摘录一下其他人的写法:
hdu 4013 子树同构问题 - YoMean!的日志 - 网易博客
http://yomean.blog.163.com/blog/static/18942022520120200323829/
HDU 4013 Distinct Subtrees(树的最小表示)_年轻_百度空间
http://hi.baidu.com/tomtongjiantao/item/0c04eb45c46b8c2a11ee1e48
HDU 4013 图论 树的最小表示 - 源码力量 - 博客频道 - CSDN.NET
http://blog.csdn.net/codeforces_sphinx/article/details/7210989
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: