Description

故事发生在1486 年的意大利,Ezio 原本只是一个文艺复兴时期的贵族,后来因为家族成员受到圣殿骑士的杀害,决心成为一名刺客。最终,凭借着他的努力和出众的天赋,成为了杰出的刺客大师,他不仅是个身手敏捷的武林高手,飞檐走壁擅长各种暗杀术。刺客组织在他的带领下,为被剥削的平民声张正义,赶跑了原本统治意大利的圣殿骑士首领-教皇亚历山大六世。在他的一生中,经历了无数次惊心动魄、扣人心弦的探险和刺杀。
曾经有一次,为了寻找Altair 留下的线索和装备,Ezio 在佛罗伦萨中的刺客墓穴进行探索。这个刺客墓穴中有许多密室,且任何两个密室之间只存在一条唯一的路径。这些密室里都有一个刺客标记,他可以启动或者关闭该刺客标记。为了打开储存着线索和装备的储藏室,Ezio 必须操作刺客标记来揭开古老的封印。要想解开这个封印,他需要通过改变某些刺客标记的启动情况,使得所有刺客标记与封印密码“看起来一样”。在这里,“看起来一样”
的定义是:存在一种“标记”密室与“密码”密室之间一一对应的关系,使得密室间的连接情况和启动情况相同(提示中有更详细解释)。幸运的是,在Ezio 来到刺客墓穴之前,在Da Vinci 的帮助下,Ezio 已经得知了打开储藏室所需要的密码。
而你的任务则是帮助Ezio 找出达成目标所需要最少的改动标记次数。

Input


第一行给出一个整数n,表示密室的个数。
第二行至第n 行,每行给出两个整数a 和b,表示第a 个密室和第b 个密室之间存在一条通道。
第n+1 行,给出n 个整数,分别表示当时每个密室的启动情况(0 表示关闭,1 表示启动)。
第n+2 行,给出n 个整数,分别表示密码中每个密室的启动情况。

Output

输出只有一行,即输出最少改动标记次数。

Sample Input

4
1 2
2 3
3 4
0 0 1 1
1 0 0 0

Sample Output

1

Data Constraint

对于30%的数据,n<=10。
对于60%的数据,n<=100。
对于100%的数据,n<=700,且每个密室至多与11 个密室相通。

Hint

样例解释:
密室的编号是可以变的!将第三个密室关闭后,在当前标记和密码之间,存在1->4,2->3,3->2,4->1 的对应关系,重新编号后连接情况没有改变,且标记与密码对应。对于更一般的情况,存在一个1 到n 的置换P,使得对于任意密室之间的道路u-v,都一定有密码密室中的道路P(u)-P(v);如果不存在密室之间的道路u-v,则一定没有密码密室中的道路P(u)-P(v)。

(题目背景吐槽:圣殿骑士团,在14世纪初被灭,根本不可能出现在1486年。)

灵感来自:https://blog.csdn.net/weixin_30932215/article/details/98347121

正解:

题目大意即:可以将一颗树随便转,要和原来的树同构,然后将两棵树对应的点异或之和取min。

确定原来树的重心为根,这样新的树的根就确定了。若重心有两个,则删掉两点连边,新开一个根节点(重心)连接两重心。(这样处理比较方便)

关于树哈希(详见oi-wiki),先存下来原先的树,后面依次搞新的树,要开long long。

枚举新的树的根,每次都做dp。f[x][y]表示 新的树以x为根的子树 与 原树以y为根的子树 相对应的异或之和。

对于每对x,y(意义同上),如何选择各自儿子的匹配?由于儿子<=11,可以用状压DP(或费用流)。g[a][b]表示匹配完了x的儿子的前i个,b表示y的儿子的匹配状态,最后用g[都匹配完]更新当前f[x][y]。

记得统计答案。

code如下,码量较大,逾200行,3000byte。

#include<bits/stdc++.h>
#define inf 1000000007
#define base 2333
#define mod (long long)((1e9)+7)
#define mid (l+r)/2
using namespace std;
int n,m,h[100005],cnt,a[1005],goal[1005],ans,fa[1005],g[15][(1<<11)+5];
int rt1,rt2,rt,size[1005],w[1005],f[1005][1005],N,fu[1005];
long long hosh[1005],hash[1005],tmp;
struct node{int next,to,bz;
}e[100005];
int read()
{int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-48;ch=getchar();}return x*f;
}
void add(int x,int y)
{//printf("Ok\n");e[++cnt].to=y;e[cnt].bz=1;e[cnt].next=h[x];h[x]=cnt;
}
void certroid(int x,int fa)
{size[x]=1;w[x]=0;for(int i=h[x];i;i=e[i].next){//printf("OK\n");int y=e[i].to;if(y!=fa){certroid(y,x);size[x]+=size[y];w[x]=max(w[x],size[y]);}}w[x]=max(w[x],n-size[x]);//printf("node[%d]s=%d w=%d\n",x,size[x],w[x]);if(w[x]<=n/2){if(!rt1)rt1=x;else rt2=x;}
}
void hdfs(int x)
{//printf("Ok %d %d\n",x,fa[x]);int tot=0;long long ans,a[15];size[x]=1;hash[x]=0;for(int i=h[x];i;i=e[i].next){int y=e[i].to;if(y!=fa[x]&&e[i].bz){fa[y]=x;hdfs(y);size[x]+=size[y];a[++tot]=hash[y];}}sort(a+1,a+tot+1);ans=0;//if(x==4)printf("find %lld\n",ans);for(int i=1;i<=tot;i++){ans=ans*base+a[i];}ans=ans*base+size[x]+1;hash[x]=ans;
}
void dp(int x,int u)
{//printf("ber %d-%d %d-%d\n",x,fa[x],u,fa[u]);f[x][u]=(a[x]^goal[u]);int sona[15],sonb[15],la=0,lb=0;for(int i=h[x];i;i=e[i].next){int y=e[i].to;if(y!=fa[x]&&e[i].bz){sona[++la]=y;}}if(!la){return;}for(int i=h[u];i;i=e[i].next){int y=e[i].to;if(y!=fu[u]&&e[i].bz){sonb[++lb]=y;}}for(int i=1;i<=la;i++){for(int j=1;j<=lb;j++){if(hash[sona[i]]==hash[sonb[j]]){dp(sona[i],sonb[j]);//    if(x==1&&u==1)printf("f[%d][%d]=%d\n",sona[i],sonb[j],f[sona[i]][sonb[j]]);}}}memset(g,0x3f,sizeof(g));int ber=g[0][0];g[0][0]=0;for(int i=0;i<la;i++){for(int s=0,ss;s<(1<<lb);s++){if(g[i][s]>=ber)continue;for(int j=1;j<=lb;j++){//if(x==2&&u==3&&i==0&&j==1&&!s)printf("BER\n");if(((1<<(j-1))&s)==0){if(hash[sona[i+1]]==hosh[sonb[j]]){ss=s+(1<<(j-1));;g[i+1][ss]=min(g[i+1][ss],g[i][s]+f[sona[i+1]][sonb[j]]);}}}}}f[x][u]+=g[la][(1<<lb)-1];//if(x==2&&u==3)printf("F %d %d\n",f[2][3],f[1][4]);
}
int main ()
{//freopen(".in","r",stdin);//freopen(".out","w",stdout);n=read();cnt=1;for(int i=1,x,y;i<n;i++) {x=read(),y=read();add(x,y);add(y,x);}for(int i=1;i<=n;i++){a[i]=read();}for(int i=1;i<=n;i++){goal[i]=read();}certroid(1,1);//printf("rt=%d %d\n",rt1,rt2);if(rt2){for(int i=h[rt1];i;i=e[i].next){int y=e[i].to;if(y==rt2){e[i].bz=e[i^1].bz=0;    }}add(n+1,rt1);add(rt1,n+1);add(n+1,rt2);add(rt2,n+1);rt=N=n+1;}else rt=rt1,N=n;fa[rt]=rt;hdfs(rt);for(int i=1;i<=N;i++){hosh[i]=hash[i];//printf("ber=%lld\n",hosh[i]);fu[i]=fa[i];}tmp=hosh[rt],ans=inf;//printf("rt=%d\n",rt);for(int i=1;i<=N;i++){fa[i]=i;//memset(size,0,sizeof(size)); hdfs(i);long long ber=hash[i];//printf("Ok %lld-%lld\n",ber,tmp);if(ber==tmp){//printf("OK %d\n",i);memset(f,0x3f,sizeof(f));dp(i,rt);ans=min(ans,f[i][rt]);}}printf("%d\n",ans);return 0;
}

Code

JZOJ3296. 【SDOI2013】刺客信条相关推荐

  1. [SDOI2013]刺客信条

    Description 故事发生在1486 年的意大利,Ezio 原本只是一个文艺复兴时期的贵族,后来因为家族成员受到圣殿骑士的杀害,决心成为一名刺客.最终,凭借着他的努力和出众的天赋,成为了杰出的刺 ...

  2. BZOJ3197:[SDOI2013]刺客信条——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=3197 故事发生在1486 年的意大利,Ezio 原本只是一个文艺复兴时期的贵族,后来因为家族成员受 ...

  3. [BZOJ3197][SDOI2013]刺客信条assassin

    bzoj luogu Description 故事发生在1486 年的意大利,Ezio原本只是一个文艺复兴时期的贵族,后来因为家族成员受到圣殿骑士的杀害,决心成为一名刺客.最终,凭借着他的努力和出众的 ...

  4. 【JZOJ3296】【SDOI2013】刺客信条(assassin)

    ╰( ̄▽ ̄)╭ Description 故事发生在1486 年的意大利,Ezio 原本只是一个文艺复兴时期的贵族,后来因为家族成员受到圣殿骑士的杀害,决心成为一名刺客.最终,凭借着他的努力和出众的天赋 ...

  5. [哈希][费用流]JZOJ 3296 【SDOI2013】刺客信条

    Description 故事发生在1486 年的意大利,Ezio 原本只是一个文艺复兴时期的贵族,后来因为家族成员受到圣殿骑士的杀害,决心成为一名刺客.最终,凭借着他的努力和出众的天赋,成为了杰出的刺 ...

  6. 【JZOJ3296】【BZOJ3197】【luoguP3296】刺客信条

    description 故事发生在1486 年的意大利,Ezio 原本只是一个文艺复兴时期的贵族,后来因为家族成员受到圣殿骑士的杀害,决心成为一名刺客.最终,凭借着他的努力和出众的天赋,成为了杰出的刺 ...

  7. 刺客信条奥德赛无法加载库_点评刺客信条起源、奥德赛、英灵殿,哪个最好玩?...

    刺客信条起源 虽然大多数玩家一直诟病刺客信条系列的高重复性,在我看来,<刺客信条:起源>是育碧将刺客信条系列转向RPG的一大艺术品.这款游戏让我感到最惊讶的是世界氛围的营造.它的历史感以及 ...

  8. luogu P3306 [SDOI2013] 随机数生成器(BSGS,数列求通项,毒瘤特判)

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 发个水题的 题解证明我还在() luogu P3306 [SDOI2013] 随机数生成器 Webli ...

  9. bzoj3122 [SDOI2013]随机数生成器

    bzoj3122 [SDOI2013]随机数生成器 给定一个递推式, \(X_i=(aX_{i-1}+b)\mod P\) 求满足 \(X_k=t\) 的最小整数解,无解输出 \(-1\) \(0\l ...

最新文章

  1. Jmeter Aggregate Report 与 Summary Report 分析
  2. 【自动驾驶】31.【相机外参标定】、【相机障碍物后处理】【地面的2D点反投影到3D】的过程对比
  3. Leetcode 40组合总数(回溯)Ⅱ41缺失的第一个正数42接雨水
  4. 缩点+染色+DFS codeforce467D
  5. java学习(72):GUL流式布局管理器
  6. Spring Cloud Hoxton正式发布,Spring Boot 2.2 不再孤单
  7. 关于Markdown编辑器怎么写“|”等特殊符号的问题
  8. 现金贷风控生命周期——贷前风控
  9. java的运行原理_Java的运行原理(转载)
  10. Linux下安装Scala
  11. Xmanager 6 激活
  12. 拦截导弹问题(递归)
  13. Jerry Wang的英语学习笔记
  14. litesql mysql 使用_Mysql 的使用方法
  15. 通过bat文件加密文件夹,放入你的秘密小电影
  16. 结束 oracle 锁 ps -ef|grepp.spid,oracle 解锁表剔除去session 和kill
  17. CleanMyMac序列号密钥如何清理苹果电脑内存?
  18. mount时发生错误:wrong fs type, bad option, bad superblock on
  19. Json代码实战演练
  20. 第四章 字体和格式相关

热门文章

  1. Textarea 自动换行实现
  2. 向我的网站添加博客- Website Builder Online Store 无代码搭建在线商城平台
  3. 7月22日,科创板正式鸣锣开市!
  4. Java API(2) File IO 异常 多线程 01-05
  5. RNG vs EDG | SKT vs KTB [20160826]
  6. Ifree黄金版最常见问题
  7. 判断坐标点是否处于某个范围内(射线法)
  8. php 接口获得图形验证码,API接口图形验证码生成
  9. 【思科CCNA理论专题:2】--ip default-network视频课程-晁海江-专题视频课程
  10. 安装固态硬盘,小米笔记本13.3