Codeforces Round #692 (Div. 2, based on Technocup 2021 Elimination Round 3) C. Peaceful Rooks 并查集

You are given a n×n chessboard. Rows and columns of the board are numbered from 1 to n. Cell (x,y) lies on the intersection of column number x and row number y.

Rook is a chess piece, that can in one turn move any number of cells vertically or horizontally. There are m rooks (m<n) placed on the chessboard in such a way that no pair of rooks attack each other. I.e. there are no pair of rooks that share a row or a column.

In one turn you can move one of the rooks any number of cells vertically or horizontally. Additionally, it shouldn’t be attacked by any other rook after movement. What is the minimum number of moves required to place all the rooks on the main diagonal?

The main diagonal of the chessboard is all the cells (i,i), where 1≤i≤n.

Input
The first line contains the number of test cases t (1≤t≤103). Description of the t test cases follows.

The first line of each test case contains two integers n and m — size of the chessboard and the number of rooks (2≤n≤105, 1≤m<n). Each of the next m lines contains two integers xi and yi — positions of rooks, i-th rook is placed in the cell (xi,yi) (1≤xi,yi≤n). It’s guaranteed that no two rooks attack each other in the initial placement.

The sum of n over all test cases does not exceed 105.

Output
For each of t test cases print a single integer — the minimum number of moves required to place all the rooks on the main diagonal.

It can be proved that this is always possible.

Example
inputCopy
4
3 1
2 3
3 2
2 1
1 2
5 3
2 3
3 1
1 2
5 4
4 5
5 1
2 2
3 3
outputCopy
1
3
4
2
Note
Possible moves for the first three test cases:

(2,3)→(2,2)
(2,1)→(2,3), (1,2)→(1,1), (2,3)→(2,2)
(2,3)→(2,4), (2,4)→(4,4), (3,1)→(3,3), (1,2)→(1,1)
**一开始写的时候以为就只有m和M+1两种可能性,写了一会发现wa4了,就说明只靠某种特殊取法是不行的 **
后来发现我的m+1情况下出现了有一个点无论到它横列的对角线还是到它纵向的对角线都有人挡着它,所以需要多走两步,那么我就可以去找这样的“环”有几个,最后我要挪动的次数就是m-在对角线上的点+n的环需要多移动的次数
cf还欠了好多题,得晚点再交利息了。。。区域赛打的铁还得去康康QAQ

#include<map>
#include<stack>
#include<queue>
#include<string>
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#define ls (k<<1)
#define rs (k<<1|1)
#define pb push_back
#define mid ((l+r)>>1)
#include<bits/stdc++.h>
using namespace std;
const int p=1e4+7;
const int mod=1e9+7;
const int maxn=1e6+1;
typedef long long ll;
const int inf=0x3f3f3f3f;
int a[20];
int root[maxn];
int find(int x)
{
    
    
    return x==root[x]?x:root[x]=find(root[x]);
}
void solve(){
    
    
    int t;
    cin>>t;
    while(t--)
    {
    
    
        ll n,m;
        cin>>n>>m;
        for(int i=1;i<=n;i++){
    
    
            root[i]=i;
        }
        ll alr=0;
        ll cyc=0;
        for(int i=1;i<=m;i++)
        {
    
    
            ll a,b;
            cin>>a>>b;
            if(a==b)
            {
    
    
                alr++;
            }
            else{
    
    
                ll x1=find(a);
                ll y1=find(b);
                if(x1!=y1){
    
    
                    root[x1]=y1;
                }
                else{
    
    
                    cyc++;
                }
            }
        }
        cout<<m-alr+cyc<<endl;
    }
}
int main()
{
    
    
   	ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
	solve();
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_45891413/article/details/111499702