More than 2019 cattle off summer school camp (ninth field) All men are brothers-- disjoint-set number of combinations &&

The meaning of problems

N-$ $ initially and do not know each individual, then $ m $ rows, each row having $ x, y $, $ represents $ Y $ and X $ friends, friends satisfies transitivity and reflexivity, each selecting the number of output current and four individuals did not know each program.

analysis

Disjoint-set and maintain the collection.

And to consider the impact of two sets of answers, the whole is minus a selected set of x, y select a collection, choose the remaining two (two from different collections).

Understand the role of $ cs $ variable on the code.

#include<bits/stdc++.h>
using namespace std;

typedef unsigned long long ll;
const int maxn = 1e5 + 10;
int n, m;
int fa[maxn], rk[maxn];

ll C4(ll x)
{
    return x * (x-1)/2 * (x-2)/3 * (x-3)/4;
}
ll C2(ll x)
{
    return x * (x-1) / 2;
}
void init()
{
    for(int i = 1;i <= n;i++)
    {
        fa[i] = i;
        rk[i] = 1;
    }
}
int find(int x)
{
    if(x != fa[x])  fa[x] = find(fa[x]);
    return fa[x];
}
void unite(int x, int y)
{
    int rx = find(x);
    int ry = find(y);
    if(rx == ry)  return;
    fa[rx] =Ry; 
    RK [Ry] + = RK [RX]; 
} 

int main () 
{ 
    Scanf ( " % D% D " , & n-, & m); 
    LL ANS = C4 (n-); 
    the printf ( " % LLD \ n- " , ANS); 

    the init (); 

    LL CS = 0 ;   // each set of two access schemes and 
    for ( int I = 0 ; I <m; I ++ ) 
    { 
        int a, B; 
        Scanf ( " % % D D " , A &, & B);
         IF(find(a) == find(b))
        {
            printf("%lld\n", ans);
            continue;
        }
        int rka = rk[find(a)], rkb = rk[find(b)];
        ll tmp1 = 1LL * rka * rkb;
        ll tmp2 = C2(n-rka-rkb) - (cs - (C2(rka)+C2(rkb)));
        cs = cs - (C2(rka)+C2(rkb)) + C2(rka+rkb);
        ans -= tmp1 * tmp2;
        printf("%lld\n", ans);
        unite(a, b);
    }
    return 0;
}

 

Guess you like

Origin www.cnblogs.com/lfri/p/11361058.html