问加几条边可以使图中的点两两到达就是使图成为连通图
也就是说所有点的根节点都指向一个点,p[i]是i的根节点,所以当p[i]==i时候,ans可以++。

并查集找连通块的个数,ans是连通块个数减去1

#include <cstdio>

const int maxn=1e5+5;
int n,m;
int p[maxn];

void init()
{
    for(int i=1;i<=n;i++)
    {
        p[i]=i;
    }
}

int find(int x)
{
    if(p[x]!=x)
    p[x]=find(p[x]);

    return p[x];

}

void unionn(int x,int y)
{
    int p1=find(x);
    int p2=find(y);

    if(p1!=p2)
    {
        p[p1]=p2;
    }
}

int main()
{
    scanf("%d %d",&n,&m);
    init();
    for(int i=1;i<=m;i++)
    {
        int x,y;
        scanf("%d %d",&x,&y);
        unionn(x,y);
    }

    int ans=0;

    for(int i=1;i<=n;i++)
    {
        if(find(i)==i)
        ans++;
    }
    ans--;
    printf("%d\n",ans);

    return 0;
}