zoukankan      html  css  js  c++  java
  • 第9场 E-All men are brothers(并查集)

    题目链接

    题意:n个人,m次操作,每次操作使得两个人(x,y)成为朋友,朋友的关系是可以传递的,计算执行每次操作后,选择四个人两两都不是朋友的不同方案的数目。

    数据范围:(n <= 100000,m <= 200000) (1 <= x <= n,1 <= y <= n,x≠y)

    输入要求:

    第一行包含两个整数,n和m

    在下面的m行中,第i行包含两个整数x和y,这意味着第x个人和 y 这个人在第一轮交友。

    第x个人和第y个人可能会在几个回合中结交朋友。

    输出要求:

    输出m + 1行,每行包含一个整数,即选出4个人的方案数。

    在每轮操作开始前和结束后输出,因此有m + 1行。

    思路:

    我们把所有是朋友的分成一个集合,x所在集合为x集合,同理y集合,其它统一为z集合(里面有若干个并查集)。若x,y在同一个集合,则为(x+y)集合

    如果x,y不在同一集合,总共有x1+z3(x里面选1个,z里面选3个), y1+z3 ,x1+y1+z2 ,z4 ,这4种情况,

    而x,y合并之后, 总共有  z4 , (x+y)1+z3【等价于 x1+z3, y1+z3】,所以如果需要合并,减去x1+y1+z2这个情况即可。

    计算:

    最开始所有人都互相不是朋友答案为 	extrm{C}_{n}^{4} ,由于n比较大,需要用到 unsigned long long;

    开始合并后:

    若x,y不在同一集合,需要合并时,减去x1+y1+z2这种情况 ,

    即 a*b*((n-a-b)*(n-a-b)-s+a*a+b*b)/2(a表示x集合人数,b表示y集合人数,s开始为总人数,更新为s+=2*a*b),这里涉及组合数学

    在同一集合时,输出上一轮的答案。

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    typedef unsigned long long ll;
    const int N=1e5+10;
    int f[N],c[N];
    ll Find(int x)
    {
        return f[x]==x?x:f[x]=Find(f[x]);
    }
    int main()
    {
        ios::sync_with_stdio(0);
        for(int i=0;i<N;i++)
            f[i]=i,c[i]=1;
        ll n; int m; cin>>n>>m;
        ll ans=n*(n-1)/2*(n-2)/3*(n-3)/4,s=n;
        while(m--){
            cout<<ans<<endl;
            int u,v; cin>>u>>v;
            u=Find(u); v=Find(v);
            if(u==v||ans==0) continue;
            ll a=c[u],b=c[v];
            ans-=a*b*((n-a-b)*(n-a-b)-s+a*a+b*b)/2;
            s+=2*a*b;
            c[v]+=c[u];
            f[u]=v;
        }
        cout<<ans<<endl;
        return 0;
    }
    View Code

     参考博客:

    https://blog.csdn.net/qq_41117236/article/details/99677875

    https://www.cnblogs.com/1625--H/p/11359772.html

  • 相关阅读:
    Captura
    食用Win系统自带的PowerShell登录服务器
    uTools
    图片镜像缓存服务
    博客园自定义网站ico
    超星图床
    教程翻译-理解基于矢量场寻路算法
    CentOS防火墙命令
    CentOS7的vsftpd安装和配置
    Unity网路编程-TCP实现细节备忘
  • 原文地址:https://www.cnblogs.com/young-children/p/11366603.html
Copyright © 2011-2022 走看看