Peaceful Rooks CodeForces - 1411C

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.
一张N×N的图,会有M个车(按象棋中车,一次可走一行)放在图中。把这些车移动到对角线上,问最少需要几步?
判断是否形成环,形成环至少需要棋子数+1,才可以。

#include<stdio.h>
int par[1001011],ans;
int find(int root)
{
    
    
    if(par[root]!=root)
        par[root]=find(par[root]);
    return par[root];
}
int merge(int r1,int r2)
{
    
    
    int p1=find(r1);
    int p2=find(r2);
    if(p1!=p2)
    {
    
    
        par[p1]=p2;
    }
    else
        ans++;
}
int main()
{
    
    
    int p;
    scanf("%d",&p);
    while(p--)
    {
    
    
        int n,m,i,r1,r2;
        ans=0;
        scanf("%d %d",&n,&m);
        for(i=1; i<=n; i++)
            par[i]=i;
        while(m--)
        {
    
    
            scanf("%d %d",&r1,&r2);
            if(r1==r2)
                continue;
            merge(r1,r2);
            ans++;
        }
        printf("%d\n",ans);
    }
}

猜你喜欢

转载自blog.csdn.net/m0_46312382/article/details/111704970
今日推荐