C. Peaceful Rooks

C. Peaceful Rooks

思路:

本题主要是要找出环,如果几个点的横纵坐标首尾能相连,则需要多一步操作,可以用并查集维护出是否在环内,不在环内贡献为1,在环内贡献为2,在对角线上不产生贡献。

代码:

#include <bits/stdc++.h>
#define PII pair<int,int>
#define LL long long
#define fi first
#define se second
#define all(x) (x).begin(),(x).end()
#define pb push_back
#define sz(x) (int)x.size()

using namespace std;

const int N = 100010;
int n, m;
int p[N];//维护出每个坐标的祖宗结点

int find(int x){
	if(x != p[x]) p[x] = find(p[x]);
	return p[x];
}

void solve()
{
	cin >> n >> m;
	for(int i = 1; i <= n; i ++ ) p[i] = i;
	LL ans = 0;
	for(int i = 1; i <= m; i ++ ){
		int x, y;
		scanf("%d %d",&x, &y);
		if(x == y) continue;
		if(find(x) == find(y)) ans += 2;//在环内,贡献为2
		else{
			p[y] = x;//p[x] = y,合并集合
			ans += 1;
		}
	}
	cout << ans << endl;
}

int main()
{
	int test = 1;
	scanf("%d",&test);
	while(test -- )
	{
		solve();
	}
	return 0;
}


posted @ 2022-02-28 22:13  合肥学院王星力  阅读(26)  评论(0)    收藏  举报