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

  首先我们知道在树的同构中树上最长链中点(如果是偶数的话就是中间两个点)是不变的,我们把这个点叫做树的重心(如果有两个重心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. activemq控制面板里的NumberOfPendingMessages、MessagesEnqueued、MessagesDequeued含义

    Number Of Consumers 消费者 这个是消费者端的消费者数量.Number Of Pending Messages 等待消费的消息 这个是当前未出队列的数量.可以理解为总接收数-总出队列 ...

  2. ADO.NET基础必备之SqlCommand.Execute三方法

    SqlCommand.ExecuteNonQuery 方法   对连接执行 Transact-SQL 语句并返回受影响的行数. ――语法: public override int ExecuteNon ...

  3. 第64天:CSS常用命名规范,有用!

    CSS常用命名,必须记住 一.常用命名 标题:title 摘要:summary 箭头:arrow 商标:label 网站标志:logo 转角/圆角:corner 横幅广告:banner 子菜单:sub ...

  4. 深入理解:java类加载器

    概念理解:Java类加载器总结 1.深入理解Java类加载器(1):Java类加载原理解析 2.深入理解Java类加载器(2):线程上下文类加载器

  5. javaBean默认接受request发送过来的数据,根据键自动设置属性

    javaBean默认接受request发送过来的数据,根据键自动设置属性

  6. 【bzoj1096】[ZJOI2007]仓库建设 斜率优化dp

    题目描述 L公司有N个工厂,由高到底分布在一座山上.如图所示,工厂1在山顶,工厂N在山脚.由于这座山处于高原内陆地区(干燥少雨),L公司一般把产品直接堆放在露天,以节省费用.突然有一天,L公司的总裁L ...

  7. 【刷题】洛谷 P4329 [COCI2006-2007#1] Bond

    题意翻译 有 \(n\) 个人去执行 \(n\) 个任务,每个人执行每个任务有不同的成功率,每个人只能执行一个任务,求所有任务都执行的总的成功率. 输入第一行,一个整数 \(n\) ( \(1\leq ...

  8. [洛谷P3250][HNOI2016]网络

    题目大意:给定一棵树.有三种操作: $0\;u\;v\;t:$在$u$到$v$的链上进行重要度为$t$的数据传输. $1\;x:$结束第$x$个数据传输. $2\;x:$询问不经过点$x$的数据传输中 ...

  9. POJ3690:Constellations——题解

    http://poj.org/problem?id=3690 题目大意:给一个图和几个子图,判断有多少种子图在原图出现过. —————————————————————— 二维哈希即可,操作看代码,我觉 ...

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

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