60pts求条玄关 马蜂良好带注释
查看原帖
60pts求条玄关 马蜂良好带注释
533102
monodev楼主2025/8/4 11:36
#include <iostream>
#include <unordered_set>
#include <vector>
using namespace std;

const int MAXN = 50000;

unordered_set<int> graph[MAXN + 5];

bool add_and_check(int i, int p1, int p2) {
	graph[i].insert(p1);
	graph[p1].insert(i);
	graph[i].insert(p2);
	graph[p2].insert(i);
	if(graph[i].size() > 2 || graph[p1].size() > 2 || graph[p2].size() > 2)
		return false;
	return true;
}

bool vis[MAXN + 5];
vector<int> seq;

int bucket[2 * MAXN + 5];

int main() {
	// 读入(set代替vector去重)
	int n;
	cin >> n;
	for(int i = 1; i <= n; ++i) {
		int p1, p2;
		cin >> p1 >> p2;
		if(!add_and_check(i, p1, p2)) {
			cout << -1 << endl;
			return 0;
		}
	}
	
	// 环 -> 序列
	int cur = 1;
	while(!vis[cur]) {
		vis[cur] = true;
		seq.push_back(cur);
		unordered_set<int>::iterator it = graph[cur].begin();
		cur = *it;
		if(vis[cur])
			cur = *(++it);
	}
	if((int)seq.size() != n) {
		cout << -1 << endl;
		return 0;
	}
	
	// 计数
	// 正着计
	int overlap = 0;
	for(int i = 0; i < n; ++i)
		bucket[seq[i] + i]++;
	for(int i = 1; i <= 2 * n; ++i)
		overlap = max(overlap, bucket[i]);
	// 反着计
	for(int i = 1; i <= 2 * n; ++i)
		bucket[i] = 0;
	for(int i = 0; i < n; ++i)
		bucket[seq[i] + n - i]++;
	for(int i = 1; i <= 2 * n; ++i)
		overlap = max(overlap, bucket[i]);
	
	cout << n - overlap << endl;
}
2025/8/4 11:36
加载中...