[bzoj3197][SDOI2013]assassin
来源:互联网 发布:java 搜狐畅言 编辑:程序博客网 时间:2024/06/06 01:35
3197: [Sdoi2013]assassin
Time Limit: 10 Sec Memory Limit: 256 MB
Submit: 221 Solved: 113
[Submit][Status][Discuss]
Description
Input
Output
Sample Input
41 22 33 40 0 1 11 0 0 0
Sample Output
1
HINT
设
在更新的时候,就相当于是这样一个问题,一些点可以和另一些点对应,每种对应都有相应的价值,问最小的价值。这很明显可以网络流。
如果x的一个儿子i可以和j对应,那么就在这两个点之间连一条
怎样判断两个点能否对应呢??
可以hash这个树,hash相同的节点就是可以对应的节点。
还有一个问题:题中给的是一个无根树,如果随便选一个节点当根hash的话,呢么选的节点不同hash值会不一样。
考虑这是一棵树,那么就可以把树的重心当根,这样树就相当于被比较平均的分开了,再hash就没什么问题了。如果这个树有两个重心的话,就再新建一个节点,分别向两个重心连边,把这个点当成重心做就行了。
#include<iostream>#include<cstdio>#include<cstring>#include<cstdlib>#include<ctime>using namespace std;#define LL unsigned int#define p 233LL#define D 1490#define T 2*n+2#define inf 707406378const int N=1500;const int M=500000;bool use[N];LL r[N],hash[N];struct S{int st,en,va,co;}aa[M],bb[N];int can,n,tot,siz[N],a[N],b[N],po[N],ne[N],point[N],next[M],l[N],dis[N],pre[N],s[N],root,o[5],f[N][N];inline void add_1(int x,int y){ ne[++tot]=po[x];po[x]=tot; bb[tot].st=x;bb[tot].en=y; ne[++tot]=po[y];po[y]=tot; bb[tot].st=y;bb[tot].en=x;}inline void get_root(int x,int last){ int i; for(siz[x]=1,i=po[x];i;i=ne[i]) if(bb[i].en!=last){ get_root(bb[i].en,x); siz[x]+=siz[bb[i].en]; s[x]=max(s[x],siz[bb[i].en]); } s[x]=max(s[x],n-siz[x]); if(s[root]==s[x]) o[++o[0]]=x; else if(s[root]>s[x]) root=x,o[o[0]=1]=x;}inline void get_hash(int x,int last){ int i; LL sum=0; for(siz[x]=1,i=po[x];i;i=ne[i]) if(bb[i].en!=last&&can!=i&&(can^1)!=i){ get_hash(bb[i].en,x); sum+=hash[bb[i].en]; siz[x]+=siz[bb[i].en]; } hash[x]=(sum*(LL)p)^r[siz[x]];}inline void add_2(int x,int y,int va,int co){ next[++tot]=point[x];point[x]=tot; aa[tot].st=x;aa[tot].en=y;aa[tot].va=va;aa[tot].co=co; next[++tot]=point[y];point[y]=tot; aa[tot].st=y;aa[tot].en=x;aa[tot].va=0;aa[tot].co=-co;}inline int SPFA(int x,int y){ int h=0,t=1,u,i; memset(use,1,sizeof(use)); memset(pre,0,sizeof(siz)); memset(dis,127/3,sizeof(dis)); l[t]=x;dis[x]=0; while(h!=t){ h=h%D+1;u=l[h];use[u]=true; for(i=point[u];i;i=next[i]) if(aa[i].va>0&&dis[aa[i].en]>dis[u]+aa[i].co){ dis[aa[i].en]=dis[u]+aa[i].co; pre[aa[i].en]=i; if(use[aa[i].en]){ use[aa[i].en]=false; t=t%D+1; l[t]=aa[i].en; } } } return dis[y];}inline int ISAP(int x,int y){ int minn=inf,i; for(i=y;i!=x;i=aa[pre[i]].st) minn=min(minn,aa[pre[i]].va); for(i=y;i!=x;i=aa[pre[i]].st){ aa[pre[i]].va-=minn; aa[pre[i]^1].va+=minn; } return minn;}inline void dp(int x,int last){ int i,j,k; for(i=po[x];i;i=ne[i]) if(bb[i].en!=last&&can!=i&&(can^1)!=i) dp(bb[i].en,x); for(i=1;i<=n;++i){ if(hash[i]==hash[x]){ memset(point,0,sizeof(point)); for(tot=1,j=po[i];j;j=ne[j]) add_2(bb[j].en+n+1,T,1,0); for(j=po[x];j;j=ne[j]) if(bb[j].en!=last&&can!=j&&(can^1)!=j){ add_2(1,bb[j].en+1,1,0); for(k=po[i];k;k=ne[k]) if(hash[bb[j].en]==hash[bb[k].en]) add_2(bb[j].en+1,bb[k].en+n+1,1,f[bb[j].en][bb[k].en]); } int minn=1,ans=0; while(minn!=inf){ minn=SPFA(1,T); if(minn!=inf) ans+=minn*ISAP(1,T); } f[x][i]=ans+(a[x]!=b[i]); } }}int main(){ srand(233); int i,x,y; scanf("%d",&n); memset(use,1,sizeof(use)); for(tot=1,i=1;i<n;++i){ scanf("%d%d",&x,&y); add_1(x,y); } for(i=1;i<=n;++i) scanf("%d",&a[i]); for(i=1;i<=n;++i) scanf("%d",&b[i]); s[0]=inf;get_root(1,0); if(o[0]==2){ for(i=po[o[1]];i;i=ne[i]) if(bb[i].en==o[2]){ can=i;break; } root=++n; a[n]=b[n]=0; add_1(n,o[1]); add_1(n,o[2]); } for(i=1;i<=n;++i) r[i]=(LL)rand(); get_hash(root,0); memset(f,127/3,sizeof(f)); dp(root,0); int ans=inf; for(i=1;i<=n;++i) ans=min(ans,f[root][i]); printf("%d\n",ans);}
1 0
- 【SDOI2013】【BZOJ3197】assassin
- [bzoj3197][SDOI2013]assassin
- [Sdoi2013]assassin
- 【JZOJ3296】【SDOI2013】刺客信条(assassin)
- BZOJ 3197 Sdoi2013 assassin 动态规划+树同构+费用流
- [KM 树同构Hash DP] BZOJ 3197 [Sdoi2013]assassin
- bzoj 3197: [Sdoi2013]assassin 树哈希+树形dp+费用流
- [Sdoi2013]spring
- [Sdoi2013]escape
- [Sdoi2013]项链
- [Sdoi2013]城市规划
- 【SDOI2013】直径
- SDOI2013 淘金
- 【SDOI2013】淘金
- 【SDOI2013】方程
- 【SDOI2013】项链
- [Sdoi2013]直径
- 【SDOI2013】森林
- 微信公众号开发
- QLibrary的使用 加载dll 使用dll中的导出方法
- 凸包Graham Scan算法实现
- Memcache知识点梳理
- 美国女生发明的「超级电容器」,20秒完成充电是什么原理?
- [bzoj3197][SDOI2013]assassin
- 人民日报:中国流失顶尖人才数居世界首位
- debug运行正常,release报错
- 2013上半年—嵌入式系统开发—末考
- iOS软件开发--OC--ARC自动引用计数
- Java FTP工具类
- [iOS]列表已读/文章收藏
- BZOJ 1485 HNOI 2009 有趣的数列 卡特兰数 线性筛法分解质因数
- 2013上半年—Linux操作系统—末考