这道题我们可以看成给定两个黑白树,可以修改其中一棵树的颜色,问最少修改多少颜色可以使两棵树同构。

  首先我们知道在树的同构中树上最长链中点(如果是偶数的话就是中间两个点)是不变的,我们把这个点叫做树的重心(如果有两个重心bz,by的话我们可以加一个点连接bx,by,将加的这个点看成重心),那么我们可以以树的重心为根来DP。

  我们可以处理使x,y为根的子树同构的最小代价,判断树同构的合法性我们可以递归的判断每一个儿子的size来判断,设x,y的子节点sonx,sony,那么假设我们求出了所有sonx,sony的值,我们可以得到状态表示,f[s]代表y子树中我们已经匹配了s集合的子节点,x子树中我们已经匹配了前|s|个节点,现在要用x子树的第|s|+1节点匹配y子树中的其他未匹配节点,然后用sonx和sony的值来更新答案。

  

/**************************************************************
Problem: 3197
User: BLADEVIL
Language: C++
Result: Accepted
Time:576 ms
Memory:884 kb
****************************************************************/

//By BLADEVIL
#include <cstdio>
#include <cstring>
#include <algorithm>
#define maxn 800
#define inf (~0U>>1) using namespace std; int n,mx,go,bx,by,rot;
int g[maxn][],a[maxn],b[maxn],s[maxn],c[maxn],f[maxn]; void dfs(int x,int fa,int dep) {
s[++s[]]=x;
if (dep>mx) {
mx=dep; go=x;
memcpy(c,s,sizeof s);
}
for (int i=;i<=g[x][];i++)
if (g[x][i]!=fa) dfs(g[x][i],x,dep+);
s[]--;
} void build(int x,int fa) {
int t[]; t[]=;
for (int i=;i<=g[x][];i++)
if (g[x][i]!=fa&&!(x==bx&&g[x][i]==by||x==by&&g[x][i]==bx))
t[++t[]]=g[x][i];
memcpy(g[x],t,sizeof t);
for (int i=;i<=g[x][];i++) build(g[x][i],x);
} int dp(int x,int y) {
if (g[x][]!=g[y][]) return inf;
int w[][];
for (int i=;i<=g[x][];i++)
for (int j=;j<=g[y][];j++)
w[i][j]=dp(g[x][i],g[y][j]);
for (int i=;i<<<g[x][];i++) f[i]=inf;
f[(<<g[x][])-]=;
for (int i=(<<g[x][])-;i;i--) {
if (f[i]<inf) {
int cnt=g[x][];
for (int j=;j<g[x][];j++)
if (i&(<<j)) cnt--;
for (int j=;j<g[x][];j++)
if (i&(<<j))
f[i^(<<j)]=min(f[i^(<<j)],f[i]+w[cnt+][j+]);
}
}
return f[]+(a[x]!=b[y]);
} int main() {
scanf("%d",&n);
for (int i=;i<n;i++) {
int x,y; scanf("%d%d",&x,&y);
g[x][++g[x][]]=y;
g[y][++g[y][]]=x;
}
for (int i=;i<=n;i++) scanf("%d",&a[i]);
for (int i=;i<=n;i++) scanf("%d",&b[i]);
dfs(,,);
dfs(go,mx=,);
if (c[]&) rot=c[+c[]>>]; else {
rot=n+;
bx=g[rot][++g[rot][]]=c[c[]>>];
by=g[rot][++g[rot][]]=c[(c[]>>)+];
}
build(rot,);
//for (int i=1;i<=n;i++) printf("%d\n",g[i][0]);
printf("%d\n",dp(rot,rot));
return ;
}

bzoj 3197 DP的更多相关文章

  1. bzoj 3622 DP + 容斥

    LINK 题意:给出n,k,有a,b两种值,a和b间互相配对,求$a>b$的配对组数-b>a的配对组数恰好等于k的情况有多少种. 思路:粗看会想这是道容斥组合题,但关键在于如何得到每个a[ ...

  2. bzoj 3197 [Sdoi2013]assassin(Hash+DP+KM)

    Description Input Output Sample Input 4 1 2 2 3 3 4 0 0 1 1 1 0 0 0 Sample Output 1 HINT [思路] Hash,D ...

  3. BZOJ 3197: [Sdoi2013]assassin 树形DP + 最小费用流 + 树的同构

    Description Input Output 其实就是给出两颗树,求一种两种树同构的方式,使得不同颜色个数最少$.$树的重新构建,其实就是指定不同的点为根节点$.$ 好在树的重心有一个重要的性质: ...

  4. BZOJ - 1003 DP+最短路

    这道题被马老板毒瘤了一下,TLE到怀疑人生 //然而BZOJ上妥妥地过了(5500ms+ -> 400ms+) 要么SPFA太玄学要么是初始化block被卡到O(n^4) 不管了,不改了 另外D ...

  5. BZOJ 2431 & DP

    题意:求逆序对数量为k的长度为n的排列的个数 SOL: 显然我们可以对最后一位数字进行讨论,判断其已经产生多少逆序对数量,然后对于前n-1位同样考虑---->每一个长度的排列我们都可以看做是相同 ...

  6. bzoj 1791 DP

    首先对于一棵树我们可以tree_dp来解决这个问题,那么对于环上每个点为根的树我们可以求出这个树的一端为根的最长链,并且在tree_dp的过程中更新答案.那么我们对于环,从某个点断开,破环为链,然后再 ...

  7. bzoj 1592 dp

    就是dp啊 f[i][j]表示到第i位,最后一位高度是j的最小花费 转移::f[i][j]=minn(f[i-1][k])+abs(a[i]-num[j]);(k<=j) #include< ...

  8. BZOJ 1207 DP

    打一次鼹鼠必然是从曾经的某一次打鼹鼠转移过来的 以打每一个鼹鼠时的最优解为DP方程 #include<iostream> #include<cstdio> #include&l ...

  9. bzoj 1925 dp

    思路:dp[ i ][ 0 ]表示第一个是山谷的方案,dp[ i ][ 1 ]表示第一个是山峰的方案, 我们算dp[ x ][ state ]的时候枚举 x 的位置 x 肯定是山峰, 然后就用组合数算 ...

随机推荐

  1. WE团队团队汇总

    WE团队目录 一.博客汇总 团队展示 选题报告 二.文档汇总 选题报告

  2. windows批处理学习(call与start)---02

    参考:https://www.cnblogs.com/Braveliu/p/5078283.html 一.call命令总结 (1)call命令简介 语法: call [ [Drive:] [Path] ...

  3. 常见设备在linux中的文件名

    设备 linux中的文件名 IDE硬盘 /dev/hd[a-d] SATA/USB/SCSI/SAS /dev/sd[a-p] 软盘 /dev/fd[0-1] 打印机 25针:/dev/lp[0-2] ...

  4. tc:逼良为娼

    tc的学习原来是想着直接从用户态学习的,但是万万没想到哇,qdisc class两个概念直接把我给搞晕了,直接看代码吧 调用:tc qdisc add dev tap0 root handle 1: ...

  5. bzoj1143-祭祀

    题目 给出一个有向无环图,要在上面安放祭祀点.两个祭祀点必须不可达,求最多能安放多少个祭祀点. 分析 由于一条无法再延伸链上只能安放一个祭祀点,而我们要求的是最多能安放祭祀点的个数,所以要求的就是最长 ...

  6. JS详细图解作用域链与闭包

    JS详细图解作用域链与闭包 攻克闭包难题 初学JavaScript的时候,我在学习闭包上,走了很多弯路.而这次重新回过头来对基础知识进行梳理,要讲清楚闭包,也是一个非常大的挑战. 闭包有多重要?如果你 ...

  7. 转 :hlda文献学习笔记

    David M.BLEI nCR文献学习笔记(基本完成了)  http://yhbys.blog.sohu.com/238343705.html 题目:The Nested Chinese Resta ...

  8. POJ3686:The Windy's——题解

    http://poj.org/problem?id=3686 题目大意: 有n个订单m个厂子,第i个订单在第j个厂子所需时间为zij,一个厂子做一个订单时不能做其他的订单. 求订单平均时间最小值. — ...

  9. Javascript让你的网页标题飘动起来

    如果你有使用WebQQ,你也许会发现,每次收到信息的时候,就会看到title提示哪个网友或群来信息,然后网页的title就会开始飘动,挺人性化,蛮有意思的.而这个效果其实也不难,这里实现了这个效果,演 ...

  10. C/C++中二维数组和指针关系分析

    在C/c++中,数组和指针有着密切的关系,有很多地方说数组就是指针式错误的一种说法.这两者是不同的数据结构.其实,在C/c++中没有所谓的二维数组,书面表达就是数组的数组.我猜想是为了表述方便才叫它二 ...