ICode9

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

Atcoder Grand Contest 038 F - Two Permutations(集合划分模型+最小割)

2021-08-08 11:02:10  阅读:302  来源: 互联网

标签:Atcoder Contest int 置换 Permutations ne ret dep ec


洛谷题面传送门 & Atcoder 题面传送门

好久前做的题了……今天偶然想起来要补个题解

首先考虑排列 \(A_i\) 要么等于 \(i\),要么等于 \(P_i\) 这个条件有什么用。我们考虑将排列 \(P_i\) 拆成一个个置换环,那么对于每一个 \(i\),根据其置换环的情况可以分出以下几类:

  • 如果 \(i\) 所在置换环大小为 \(1\),即 \(P_i=i\),那么 \(A_i\) 别无选择,只能等于 \(i\)
  • 如果 \(i\) 所在置换环大小不为 \(1\),那么 \(A_i\) 有两种选择,\(A_i=i\) 或者 \(A_i=P_i\)
    • 如果 \(A_i=i\),那么假设 \(j\) 为满足 \(P_j=i\) 的位置,那么由于排列中元素不能重复,因此 \(A_j\ne P_j=i\),即 \(A_j=j\),我们再找出 \(P_k=j\) 的 \(k\),也应有 \(A_k=k\),这样即可确定整个置换环上元素的情况。
    • 如果 \(A_i=P_i\),类似地,设 \(j=P_i\),那么 \(A_j\ne j\),因为排列中元素不能重复,故 \(A_j=P_j\),我们再找出 \(k=P_j\) 的位置 \(k\),也应有 \(A_k=P_k\),这样也能够确定整个置换环的 \(A\)。

也就是说,对于一个置换环而言,我们可以将其视作一个整体看待——这个置换环中要么所有元素的 \(A_i\) 都等于其本身,要么所有元素的 \(A_i\) 都等于 \(P_i\),为了使表述更加具体形象,我们把前一种情况称作“转”(orz wlzhouzhuan),后一种情况称作“不转”。那么对于每一个下标 \(i\),它是否产生的 \(A_i=B_i\) 的情况如下:

  • 如果 \(i=P_i=Q_i\),那么不管怎样都有 \(A_i=B_i\),我们完全可以直接令答案加一,并忽略这种情况。
  • 如果 \(i=P_i\ne Q_i\),那么若 \(Q_i\) 所在置换环不转就会有 \(A_i=B_i=i\),对答案产生 \(1\) 的贡献,若 \(Q_i\) 所在置换环转则不会产生这样的情况。
  • 如果 \(i=Q_i\ne P_i\),同理,若 \(P_i\) 所在置换环不转则重复元素个数 \(+1\),否则重复元素个数不变。
  • 如果 \(i\ne P_i=Q_i\),那么如果 \(P_i\) 所在置换环与 \(Q_i\) 所在置换环同时转/同时不转那么重复元素个数 \(+1\),否则重复元素个数不变。
  • 如果 \(i\ne P_i\ne Q_i\),那么如果 \(P_i\) 所在置换环与 \(Q_i\) 所在置换环同时不转那么重复元素个数 \(+1\),否则重复元素个数不变。

如果我们将每个置换环“转”看作被划分入 A 集合,“不转”看作被划分入 B 集合,那么上述条件可以转化为:

  • \(i=P_i\ne Q_i\):如果 \(Q_i\) 所在置换环属于 B 那么答案加 \(1\)
  • \(i=Q_i\ne P_i\):如果 \(P_i\) 所在置换环属于 B 那么答案加 \(1\)
  • \(i\ne P_i=Q_i\):如果 \(P_i,Q_i\) 所在置换环属于相同集合那么答案加 \(1\)
  • \(i\ne P_i\ne Q_i\):如果 \(P_i,Q_i\) 都属于 B 集合那么答案加 \(1\)

看到“划分为两个集合”,“如果两点属于相同/不同集合则代价加 \(1\),求最小/最大代价”之类的字眼,我们能够想到……最小割!具体来说,我们将每个置换环看作一个点,并新建源汇,我们定义 \(P\) 中的置换环转当且仅当其与 \(S\) 相连,不转当且仅当其与 \(T\) 相连;\(Q\) 中的置换环转当且仅当其与 \(T\) 相连,不转当且仅当其与 \(S\) 相连,这样所有代价都可以用一/两条网络流上的 \(1\) 权边的形式表述,再根据最大流 \(=\) 最小割求出最小代价即可。

时间复杂度同 dinic 求二分图匹配,\(\mathcal O(n\sqrt{n})\)。

const int MAXN=1e5;
const int MAXV=1e5+2;
const int MAXE=2e5*2;
const int INF=0x3f3f3f3f;
int n,a[MAXN+5],b[MAXN+5],S=1e5+1,T=1e5+2,ncnt=0;
int bel_a[MAXN+5],bel_b[MAXN+5];
int hd[MAXV+5],to[MAXE+5],cap[MAXE+5],nxt[MAXE+5],ec=1;
void adde(int u,int v,int f){
	to[++ec]=v;cap[ec]=f;nxt[ec]=hd[u];hd[u]=ec;
	to[++ec]=u;cap[ec]=0;nxt[ec]=hd[v];hd[v]=ec;
} int dep[MAXV+5],now[MAXV+5];
bool getdep(){
	memset(dep,-1,sizeof(dep));dep[S]=0;
	queue<int> q;q.push(S);now[S]=hd[S];
	while(!q.empty()){
		int x=q.front();q.pop();
		for(int e=hd[x];e;e=nxt[e]){
			int y=to[e],z=cap[e];
			if(z&&!~dep[y]){
				dep[y]=dep[x]+1;
				now[y]=hd[y];q.push(y);
			}
		}
	} return ~dep[T];
}
int getflow(int x,int f){
	if(x==T) return f;int ret=0;
	for(int &e=now[x];e;e=nxt[e]){
		int y=to[e],z=cap[e];
		if(z&&dep[y]==dep[x]+1){
			int w=getflow(y,min(f-ret,z));
			ret+=w;cap[e]-=w;cap[e^1]+=w;
			if(f==ret) return ret;
		}
	} return ret;
}
int dinic(){
	int ret=0;
	while(getdep()) ret+=getflow(S,INF);
	return ret;
}
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++) scanf("%d",&a[i]),++a[i];
	for(int i=1;i<=n;i++) scanf("%d",&b[i]),++b[i];
	for(int i=1;i<=n;i++) if(!bel_a[i]){
		bel_a[i]=(i^a[i])?(++ncnt):ncnt;int cur=a[i];
		while(cur^i) bel_a[cur]=ncnt,cur=a[cur];
	}
	for(int i=1;i<=n;i++) if(!bel_b[i]){
		bel_b[i]=(i^b[i])?(++ncnt):ncnt;int cur=b[i];
		while(cur^i) bel_b[cur]=ncnt,cur=b[cur];
	} int res=n;
	for(int i=1;i<=n;i++){
		if(a[i]==i&&b[i]==i) res--;
		else if(a[i]!=i&&b[i]!=i){
			if(a[i]==b[i]) adde(bel_a[i],bel_b[i],1),adde(bel_b[i],bel_a[i],1);
			else adde(bel_b[i],bel_a[i],1);
		} else {
			if(a[i]==i) adde(bel_b[i],T,1);
			else adde(S,bel_a[i],1);
		}
	} printf("%d\n",res-dinic());
	return 0;
}

标签:Atcoder,Contest,int,置换,Permutations,ne,ret,dep,ec
来源: https://www.cnblogs.com/ET2006/p/agc038F.html

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

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

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

ICode9版权所有