【题解】洛谷P8346:最澄澈的空与海

【题解】洛谷P8346:最澄澈的空与海

猜结论题,本身其实很简单,在纸上画个差不多就能想出来,我一开始想二分图最大匹配,但是还是太大了,不可以。

当一个二分图有且仅有一种解时,必定有节点的入度为 \(1\)

我们想到有多种匹配的情况,可以想到如果这是一个环的情况,一个左边的点将他右边的点都标记后另一个点再遍历出边后没有可以连的右点了就说明有环的,我们可以用拓扑保证复杂度与正确性,具体怎么做我省略,具体看代码。

image

#include <bits/stdc++.h>
#define int long long
#define ls p<<1
#define rs p<<1|1 
#define re register 
const int N=2e6+10;
const int mod=1000;
using namespace std;

int t;
int n,m;

vector<int> v[N];
int du[N];
int vis[N];
int ans=0;
queue<int> q;
int solve(){
	ans=0;
	cin>>n>>m;
	
	for(int i=1;i<=m;i++){
		int u,vv;
		cin>>u>>vv;
		v[u].push_back(vv+n);
		v[vv+n].push_back(u);
		du[u]++;
	}
	
	for(int i=1;i<=n;i++){
		if(!du[i]){
			return 0;
		}
		if(du[i]==1){
			q.push(i);
			ans++;
		}
	}
	
	while(!q.empty()){
		int x=q.front();
		q.pop();
		for(int i=0;i<v[x].size();i++){
			int y=v[x][i];
			if(vis[y]){
				continue;
			}
			vis[y]=1;
			
			for(int k=0;k<v[y].size();k++){
				int yy=v[y][k];
				if((--du[yy])==1){
					q.push(yy);
					ans++;
				}
			}
		}
	} 
	return ans==n;
}

signed main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr); 
	cin>>t;
	while(t--){
		if(solve()){
			cout<<"Renko\n";
		}
		else{
			cout<<"Merry\n";
		} 
		while(!q.empty()){
			q.pop();
		}
		for(int i=1;i<=2*n;i++){
			v[i].clear();
			du[i]=0;
			vis[i]=0;
		}
	} 
	return 0;
}
posted @ 2024-11-12 16:21  sad_lin  阅读(0)  评论(0编辑  收藏  举报