博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[JZOJ3296] 【SDOI2013】刺客信条
阅读量:4965 次
发布时间:2019-06-12

本文共 1982 字,大约阅读时间需要 6 分钟。

题目大意

给你一棵树,树上每个节点有000111的状态。

用最少的操作次数使得当前状态与目标状态同构。


思考历程

首先想到的是找重心。

因为根是不确定的,但重心只会有一个或两个,以重心为根就能方便很多。
如果重心有两个,就将连接它们的边拆成点,让它们分别与这个点相连就好了(重心是连在一起的)。
然后就是树上哈希……
哈希之后就开始了艰辛的思考历程……
于是比赛就结束了。


正解

我前面的思考是没有问题的。

后面的该怎么处理?当然是DP啊!
fi,jf_{i,j}fi,j表示子树iii对应子树jjj的最小操作数。
显然如果iii能匹配jjj,就必须要保证它们的哈希值相等。
但是还会有其它条件,综合起来就是它们祖先的哈希值也相等……
其实为了简化操作,我们再保证它们的深度相等就行了,虽然这并不能保证它们真的能够匹配,但也就算了吧……(我曾试过将完全出去这些冗余状态,但程序跑得更慢了,这意味着数据的这一类冗余状态并不多)
所以可以将点按照深度和哈希值排序,从后往前做。
接下来考虑转移,首先ai xor bja_i \ xor \ b_jai xor bj是一定要加上的、
然后就将各自的子树两两配对,也就是∑fx,y\sum f_{x,y}fx,y,其中xxxiii的儿子,yyyjjj的儿子,而且xxxyyy哈希值相等。
我们要保证这个东西最小。
于是这就变成了二分图的最小权完备匹配。
题目说每个点的度数小于等于111111,这意味着看起来能够状压DP。
但实际上,如果不非常用力地开常数,那状压DP是很难卡过去的……(我打了80分)。
于是就可以用费用流或KM算法(因为这题求的是最小权,所以将边权取相反数就可以了)。
时间复杂度为玄学……


代码

状压DP

using namespace std;#include 
#include
#include
#define N 710#define mod 1000000007inline void get_min(int &a,int b){
a>b?a=b:0;}int n;int e[N][11],ne[N];int bz[N][11],nbz;int siz[N];int tmpr[2],cnt,root;void get_siz(int x,int fa){
bool is_root=1; siz[x]=1; for (int i=0;i
=1;ii=q[--i]){
for (int j=i,jj=q[j];j>=1 && dep[ii]==dep[jj] && h[ii]==h[jj];jj=q[--j]){
memset(g,63,sizeof g); g[0][0]=0; for (int x=0;x
>y&1) continue; get_min(g[x+1][k|1<
>x&1) continue; get_min(g[y+1][k|1<

KM算法

using namespace std;#include 
#include
#include
#define N 710#define mod 1000000007inline void get_min(int &a,int b){
a>b?a=b:0;}int n;int e[N][11],ne[N];int bz[N][11],nbz;int siz[N];int tmpr[2],cnt,root;void get_siz(int x,int fa){
bool is_root=1; siz[x]=1; for (int i=0;i
=1;ii=q[--i]){
for (int j=i,jj=q[j];j>=1 && dep[ii]==dep[jj] && h[ii]==h[jj];jj=q[--j]){
calc(ii,jj); if (ii!=jj) calc(jj,ii); } } printf("%d\n",f[root][root]); return 0;}

总结

想不出来的东西就用网络流吧……

转载于:https://www.cnblogs.com/jz-597/p/11145215.html

你可能感兴趣的文章
Ubuntu下如何访问Windows磁盘?
查看>>
Rabbitmq安装及启动 MAC系统
查看>>
nginx location配置
查看>>
在DELPHI中动态创建控件以及控件的事件(转)配合 让FIREDAC记录数据库的异常日志...
查看>>
WordPress程序文件说明
查看>>
6.6410和210的按键中断编程
查看>>
PHP处理数组和XML之间的互相转换
查看>>
办公室文员、助理都可以学学,留着迟早用得着!
查看>>
使用httpModule做权限系统
查看>>
aiohttp异步爬虫爬取当当网最热书籍并导出excel
查看>>
奇异矩阵(转载)
查看>>
打飞机
查看>>
MVC3.0 中Razor 学习
查看>>
<转> mysql处理高并发,防止库存超卖
查看>>
[18/11/29] 继承(extends)和方法的重写(override,不是重载)
查看>>
Numpy基础操作笔记
查看>>
How can I add a new user as sudoer using the command line?
查看>>
UI的设计,适配器,以及RecyclerView无法加载的解决办法
查看>>
SpringBoot集成netty实现客户端服务端交互和做一个简单的IM
查看>>
Math.ceil()、Math.floor()和Math.round()
查看>>