Codeforces1411 C. Peaceful Rooks(思维,并查集)

题意:

在这里插入图片描述

解法:

设点的坐标为(x,y),如果可以一步走过去,那么一步即可,
如果有多个点卡在一起,那么就需要多走一步,例如:
在这里插入图片描述
上图中三个点卡在一起,导致每个点既不能一步到达(x,x),也不能一步到达(y,y),那么总步数就需要+1。

那么如何判断是否冲突了呢?
可以用并查集维护,对于点(x,y),用并查集合并x和y,表示(x,x)和(y,y)在一个点的攻击范围内,
如果合并之前发现x和y已经在同一集合,那么说明和其他点出现了冲突,此时总步数需要+1。

最后要注意的是,如果一个点一开始就在对角线上,那么忽略不计。

code:

#include <bits/stdc++.h>
#define int long long
#define PI pair<int,int>
using namespace std;
const int maxm=2e6+5;
int pre[maxm];
int cnt[maxm];
int mark[maxm];
int n,m;
int ffind(int x){
    
    
    return pre[x]==x?x:pre[x]=ffind(pre[x]);
}
void solve(){
    
    
    cin>>n>>m;
    for(int i=1;i<=n;i++){
    
    
        pre[i]=i;
        cnt[i]=1;
        mark[i]=0;
    }
    int ans=0;
    for(int i=1;i<=m;i++){
    
    
        int a,b;cin>>a>>b;
        if(a==b)continue;
        int x=ffind(a);
        int y=ffind(b);
        if(x!=y){
    
    
            pre[x]=y;
        }else{
    
    //出现环,需要额外走一步
            ans++;
        }
        ans++;
    }
    cout<<ans<<endl;
}
signed main(){
    
    
    ios::sync_with_stdio(0);
    int T;cin>>T;
    while(T--){
    
    
        solve();
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_44178736/article/details/115005327
今日推荐