首页 > 其他分享 >(图论分析,思维)ABC 350-D

(图论分析,思维)ABC 350-D

时间:2024-04-23 22:11:29浏览次数:23  
标签:200001 图论 ABC f1 int 查集 350 边数 Find

背景:我自己思考想出来的图论题,总归是有成就感的
分析:求间接连接的点的对数,即一个连通块中枚举出两两连接的组合数,减去整个连通块中的边数,因为一条边必然直接连接了两个不同的点
原理:并查集
时间复杂度:o(n)
代码如下:

点击查看代码
#include <bits/stdc++.h>
using namespace std;
int f[200001];//并查集
int e[200001];//代表每个节点直接相连有多少边
int big[200001];//记录每个连体块的大小,即含多少个节点(以祖先为代表)
int connect[200001];//记录每个连通块的含边数
int Find(int x)//并查集查找
{
    if(x == f[x]) return x;
    else return f[x] = Find(f[x]);
}
int main()
{
    ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);//加快输入输出
    int n,m,x,y;
    cin>>n>>m;//输入节点数及边数
    for (int i = 1;i<=n;i++) f[i] = i;//并查集初始化别忘了
    for (int i = 1;i<=m;i++)//依次输入m条边
    {
        cin>>x>>y;
        e[x]++;//边数累加
        e[y]++;
        int f1 = Find(x);
        int f2 = Find(y);
        if(f1 == f2) continue;
        f[f1] = f2;//并查集合并
    }
    for (int i = 1;i<=n;i++)//预处理连通块
    {
        x = Find(i);
        big[x]++;//对应连通块大小加1
        connect[x] += e[i];//连通块含边数加上当前节点带来的边
    }
    long long ans = 0;//初始化答案
    for (int i = 1;i<=n;i++)//求和
    {
        x = Find(i);
        if(x != i) continue;//不是祖先跳过
        connect[x] /= 2;//因为之前连通块中每条边重复计算了2次,故要除以2
        long long temp = (long long)(big[x])*(big[x]-1)/2;//计算答案
        ans += (temp - connect[x]);//累加
    }
    cout<<ans<<"\n";//输出
    return 0;
}

标签:200001,图论,ABC,f1,int,查集,350,边数,Find
From: https://www.cnblogs.com/cuijunjie18/p/18153881

相关文章

  • AtCoder Beginner Contest 350 A - G 题解
    AtCoderBeginnerContest350A-PastABCsSolution把最后三个字符转成数字判断即可Code#include<bits/stdc++.h>usingnamespacestd;intmain(){strings;cin>>s;s=s.substr(3,3);intx=0;x=(s[0]-'0')*100+(s[1]-�......
  • ABC350C 题解
    怎么赛时连这道都不会了/ll注意到输入是个排列,这意味着我们可以直接确定每个元素应在的位置。考虑维护每个数当前所在的位置\(\{p\}\)。对于任意\(i\in[1,n]\),我们访问\(p_i\),如果该位置不为第\(i\)位便对排列中第\(i\)位的数\(j\)和\(i\)进行“交换”操作。“......
  • 【图论】最短路练习——P1629邮递员送信
    邮递员送信题目描述有一个邮递员要送东西,邮局在节点\(1\)。他总共要送\(n-1\)样东西,其目的地分别是节点\(2\)到节点\(n\)。由于这个城市的交通比较繁忙,因此所有的道路都是单行的,共有\(m\)条道路。这个邮递员每次只能带一样东西,并且运送每件物品过后必须返回邮局。求送完......
  • 「杂题乱刷」AT_abc279_e
    链接很一眼。容易发现除非操作时影响\(1\)这个数字,否则答案一定改变,直接特判影响到\(1\)这个数字的两种情况即可。代码:点击查看代码/*Tips:你数组开小了吗?你MLE了吗?你觉得是贪心,是不是该想想dp?一个小时没调出来,是不是该考虑换题?*/#include<bits/stdc++.h>using......
  • 「杂题乱刷」AT_abc253_c
    感觉要好好补补set了。链接直接用set模拟即可。点击查看代码/*Tips:你数组开小了吗?你MLE了吗?你觉得是贪心,是不是该想想dp?一个小时没调出来,是不是该考虑换题?*/#include<bits/stdc++.h>usingnamespacestd;#definemapunordered_map#defineforl(i,a,b)for(re......
  • ABC350
    E.杀了我个措手不及的记忆化搜索。首先观察\(N\leq10^{18}.\)但是这却是个不用矩快的\(DP.\)设\(f[x]\)为\(x\)的答案。有以下两种决策:第一种:\(f[x]=f[x/A]+X\),也就是直接执行第一种方案。第二种:掷出\(Dice\),然后考虑\(Dice\)的期望。\(f[x]=\dfrac{f[x]+f[x/2......
  • AtCoder Beginner Contest 350 G - Mediator
    链接:https://atcoder.jp/contests/abc350/tasks/abc350_g大致题意:给出n个点,q个询问1号询问要求u,v之前加一条无向边图始终是一个森林2号询问询问是否有一个点与u,v都相邻,若有则输出该点,若无则输出0。询问强制在线。思路:在题目要求的图中,满足2号询问的点只有三种情况:要么这个......
  • ABC 287 D - Match or Not
    题目链接:第一次提交:依据题意直接模拟,喜提\(\sfTLE\)。#include<bits/stdc++.h>usingnamespacestd;boolcheck(stringa,stringb){ for(inti=0;i<a.size();i++){ if(a[i]=='?'&&b[i]!='?')a[i]=b[i]; elseif(......
  • AtCoder Beginner Contest 350
    B-DentistAoki难度:⭐题目大意现在有数列1~n,现在有m次操作,每次给出一个x,如果x存在就是删去,不存在就加上;问最后数列还剩多少个;解题思路数据很小,暴力就行;神秘代码#include<bits/stdc++.h>#defineintlonglong#defineIOSios::sync_with_stdio......
  • Atcoder ABC 350 全题解
    题外话别以为博主之前几场ABC都咕咕咕了,最近状态不好,这次ABC终于回来了(也有可能是题目变容易了,有图为证)P.S.请耐心看到最后!!否则后果自负!!!AB这年头谁不会AB啊当然有。不学OI的人。C考虑选择排序,依次将$1,2,3\cdots$与它们应该在的位置进行交换。那如果真的......