正题
大意
两棵树,它们的相似值是它们留下最多的节点使它们的结构相同。求相似值。
这两颗树就是结构相同的,相似值是8。
解题思路
就是树形dp。可以用f[i][j]f[i][j]表示树1的第ii号节点和它的子树与树2的号节点与它的子树的相似值,然后每个叶子节点的相似值就是1,然后每两个非子节点的相似值就是它们的子节点之间相互匹配的最大价值,由于数据较小所以我们可以O(5!)O(5!)暴力枚举,时间复杂度O(n2×5!)O(n2×5!)。
代码
#include<cstdio>
#include<vector>
#include<cstring>
#include<algorithm>
#define MN 1001
using namespace std;
struct node{int to,next;
}a1[MN],a2[MN];
vector<int> s1[MN],s2[MN];
bool v[MN];
int f[MN][MN],n,x,y,m;
void zdfs(int k,int sum)
{if (k>=s1[x].size()){f[x][y]=max(f[x][y],sum);return;}zdfs(k+1,sum);bool pd=false;for (int i=0;i<s2[y].size();i++)if (!v[i]){pd=true;v[i]=true;//标记zdfs(k+1,sum+f[s1[x][k]][s2[y][i]]);//搜索下一个v[i]=false;//回溯}if (pd) f[x][y]=max(f[x][y],sum);
}
void dfs(int k)
{if (!s1[k].size()){for (int i=1;i<=m;i++)f[k][i]=1;//叶子节点相似值为1return;}for (int i=0;i<s1[k].size();i++)dfs(s1[k][i]);//dp子节点for (int i=1;i<=m;i++){if (!s2[i].size()) f[k][i]=1;//对面为叶子节点也是相似值为1else{x=k;y=i;zdfs(0,0);//暴力匹配f[k][i]++;//算上自己}}
}
int main()
{scanf("%d%d",&n,&m);for (int i=1;i<n;i++){scanf("%d%d",&x,&y);s1[x].push_back(y);}for (int i=1;i<m;i++){scanf("%d%d",&x,&y);s2[x].push_back(y);}dfs(1);//dpprintf("%d",f[1][1]);
}