AtCoder Beginner Contest 350 English ouyuYO (Contestant) D - New Friends

就写到了D, 计算完全连同图的边数那里忘加了小括号,找了很久。

D - New Friends

        提取题意就是说每个连通图还需要连多少条边才能成为完全连通图。所以就要用并查集了,但在用并查集的时候还要同时统计当前连通图的已有边数,以便于计算还需要多少。

#include<bits/stdc++.h>
#define IOS ios::sync_with_stdio(0);cin.tie(0)
#define int long long 
using namespace std ;
typedef pair<int,int> PII ;
const int N = 1e6 + 10 ;
const int INF = 0x3f3f3f3f ;
const int MOD = 998244353 ;
int T ;
int n, m;
int a[N] ;
int b[N] ;
vector<PII> op ;
PII p[N] ;
int find(int k){
    if(p[k].second != k){
        p[k].second = find(p[k].second) ;
    }
    return p[k].second ;
}
void merge(int a,int b){
    if(find(a) != find(b)) p[find(a)].first += p[find(b)].first + 1  ;//不同集合,加上另一集合的边数再加1
    else{
        p[find(a)].first ++ ;//同一集合只加一条
    }
    p[find(b)].second = find(a) ;
}

int calc(int k){
    return (k * (k - 1)) / 2 ;
}
void solve(){
    cin >> n  >> m ;
    for(int i = 1 ; i <= n ; ++ i){
        p[i].second = i ;
        p[i].first = 0 ;
    }
    int l, r ;
    set<PII> se ;
    for(int i = 1; i <= m ; ++ i){
        cin >> l >> r ;
        if(se.find({l,r}) == se.end()){
            se.insert({l,r}) ;
            se.insert({r,l}) ;
            merge(l,r) ;
        }

    }
    map<int,int> mp ;
    int sum = 0 ;
    for(int i = 1 ; i <= n ; ++ i){
        mp[p[find(i)].second] ++ ;
    }
    // cout << mp.size() << endl ;
    for(auto e:mp){
        sum += calc(e.second) - p[e.first].first ;
        // cout << e.first <<" "<< p[e.first].first << " " << e.second << endl ;
    } 
    cout << sum << endl ;

    
    return ;

}
signed main(){
    IOS ;
    // cin >> T ;
    T = 1 ;
    while(T--){
        solve() ;
    }
    return 0 ;
}

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

鴎羽

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值