CF1867D Cyclic Operations

事實上我們可以發現,如果\(b_i=x\)最後,那麼我們可以連一條邊,從\(i\)\(x\)

這樣我們就得到了一個有向圖,在這張有向圖呢,可以證明的是

如果\(k=1\),那麼必須全部都是自環。

若不成立,則必須每個環的大小恰好爲\(k\)

這樣就可以解決了。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<stack>
#include<set>
#include<map>
#include<ctime>
#include<bitset>
using namespace std;
int t;
int to[200005];
int ff;
int n,k;
int b[200005];
int du[200005];
int vis[200005];
queue<int> q;
void dfs(int now,int f,int l){
	if(to[now]==f){
		du[to[now]]--;
		if(l!=k) ff=0;
		return ;
	}
	du[to[now]]--;
	dfs(to[now],f,l+1);
	return ;
}
void print(){
	printf("%s\n",(ff==1?"Yes":"No"));
}
int main(){
	scanf("%d",&t);
	while(t--){
		scanf("%d%d",&n,&k);
		for(int i=1;i<=n;++i){
			scanf("%d",&b[i]);
		}
		ff=1;
		if(k==1){
			ff=1;
			for(int i=1;i<=n;++i){
				if(b[i]!=i) ff=0;
			}
			print();
		}else{
			memset(du,0,sizeof(du));
			for(int i=1;i<=n;++i){
				to[i]=b[i];
				du[b[i]]++;
			}
			while(!q.empty()) q.pop();
			for(int i=1;i<=n;++i){
				if(du[i]==0) q.push(i);
			}
			while(!q.empty()){
				int x=q.front();
				q.pop();
				du[to[x]]--;
				if(du[to[x]]==0) q.push(to[x]);
			}
			for(int i=1;i<=n;++i){
				if(du[i]!=0){
					dfs(i,i,1);
					if(!ff) break;
				}
			}
			print();
		}
	}
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章