ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

luogu P3296 [SDOI2013]刺客信条

2021-08-14 08:31:07  阅读:231  来源: 互联网

标签:Me int luogu void P3296 ny add SDOI2013 define


题面传送门
首先肯定要找到任意一个在所有形态树中都一样的点,那么肯定找到重心。
然后找到中心以后设\(dp_{i,j}\)为\(i\)与\(j\)子树的最小答案。
然后对于这两个点的子树KM一下就可以得到答案了再加上自己。
时间复杂度\(O(11n^2)\)
code:

#include<bits/stdc++.h>
#define I inline
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define abs(x) ((x)>0?(x):-(x))
#define re register
#define ll long long
#define db double
#define lb long db
#define N 700
#define K 20
#define mod 998244353
#define Mod 998244352
#define eps (1e-4)
#define U unsigned int
#define it iterator
#define Gc() getchar() 
#define Me(x,y) memset(x,y,sizeof(x))
#define d(x,y) (n*(x-1)+(y))
using namespace std;
int n,m,k,x[N+5],y[N+5],root,dp[N+5][N+5],A[N+5],B[N+5],nx,ny,cnt,siz[N+5],F[N+5];vector<int> Son[N+5];
struct yyy{int to,z;};
struct ljb{int head,h[N+5];yyy f[N+5<<1];I void add(int x,int  y){f[++head]=(yyy){y,h[x]};h[x]=head;}}s,Cl;
struct Graph{
	int n,W[K+5][K+5],vx[K+5],vy[K+5],px[K+5],py[K+5],pre[K+5],slack[K+5],lx[K+5],ly[K+5],ToT;queue<int> Q;
	I void clear(){Me(W,-0x3f);Me(lx,-0x3f);Me(ly,0);Me(px,0);Me(py,0);Me(pre,0);}
	I void aug(int x){while(x) py[x]=pre[x],swap(x,px[pre[x]]);}
	I void insert(int x,int y,int z){n=z;for(int i=0;i<n;i++) for(int j=0;j<n;j++) W[i+1][j+1]=max(W[i+1][j+1],-dp[Son[x][i]][Son[y][j]]),lx[i+1]=max(lx[i+1],-dp[Son[x][i]][Son[y][j]]);}
	I void bfs(int x){
		Me(vx,0);Me(vy,0);Me(slack,0x3f);re int i;while(!Q.empty()) Q.pop();Q.push(x);while(1){
			while(!Q.empty()){
	    		x=Q.front();Q.pop();vx[x]=1;for(i=1;i<=n;i++){
		    		if(vy[i]||slack[i]<=lx[x]+ly[i]-W[x][i]) continue;pre[i]=x;slack[i]=lx[x]+ly[i]-W[x][i];if(!slack[i]){vy[i]=1;if(!py[i]) return aug(i);Q.push(py[i]);}
	    		}
	    	}ToT=1e9;for(i=1;i<=n;i++) !vy[i]&&(ToT=min(ToT,slack[i]));for(i=1;i<=n;i++) vx[i]&&(lx[i]-=ToT),vy[i]?(ly[i]+=ToT):(slack[i]-=ToT);for(i=1;i<=n;i++) if(!slack[i]&&!vy[i]){vy[i]=1;if(!py[i]) return aug(i);Q.push(py[i]);}
		}
	}
	I int KM(){re int i;for(i=1;i<=n;i++) bfs(i);for(ToT=0,i=1;i<=n;i++)ToT+=lx[i]+ly[i];return -ToT;}
}T;
I void Make(int x,int last){siz[x]=1;yyy tmp;for(int i=s.h[x];i;i=tmp.z)tmp=s.f[i],tmp.to^last&&(Make(tmp.to,x),siz[x]+=siz[tmp.to],F[x]=max(F[x],siz[tmp.to]));F[x]=max(F[x],n-siz[x]);}
I void dfs(int x,int last){yyy tmp;for(int i=s.h[x];i;i=tmp.z) tmp=s.f[i],tmp.to^last&&(dfs(tmp.to,x),Son[x].push_back(tmp.to),0);}
I void GetAns(int x,int y){
	if(Son[x].size()^Son[y].size()){dp[x][y]=1e3;return;}re int i,j;for(i=0;i<Son[x].size();i++){
		for(j=0;j<Son[y].size();j++)GetAns(Son[x][i],Son[y][j]);
	}T.clear();T.insert(x,y,Son[x].size());dp[x][y]=T.KM()+(A[x]^B[y]);
}
int main(){
//	freopen("1.in","r",stdin);
	re int i;scanf("%d",&n);for(i=1;i<n;i++) scanf("%d%d",&x[i],&y[i]),s.add(x[i],y[i]),s.add(y[i],x[i]);Make(1,0);for(i=1;i<=n;i++) F[i]<=n/2&&(cnt++,root=i);for(i=1;i<=n;i++) scanf("%d",&A[i]);for(i=1;i<=n;i++) scanf("%d",&B[i]);
	if(cnt==2){s=Cl;for(i=1;i<=n;i++) F[i]<=n/2&&((nx?ny:nx)=i);s.add(nx,n+1);nx>ny&&(swap(nx,ny),0);s.add(n+1,nx);s.add(n+1,ny);s.add(ny,n+1);for(i=1;i<=n;i++) (min(x[i],y[i])^nx||max(x[i],y[i])^ny)&&(s.add(x[i],y[i]),s.add(y[i],x[i]),0);n++;root=n;}
	dfs(root,0);GetAns(root,root);printf("%d\n",dp[root][root]);
}

标签:Me,int,luogu,void,P3296,ny,add,SDOI2013,define
来源: https://www.cnblogs.com/275307894a/p/15139827.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有