CF744A Hongcow Builds A Nation 题解

题目翻译

给出一张 \(n\) 个点, \(m\) 条边的无向图,其中有\(k\)个点是警察局。

一个稳定的图要满足以下条件:

  • 无重边。
  • 无自环。
  • 每个连通块内最多只有一个警察局。

你的任务是求最多还能加多少条边,使得加完边后的图还能是稳定的。

思路/算法

主要是并查集、图论。

下面是关于并查集的介绍,这里只做基本介绍,本题只涉及较基础的并查集,可以看代码。

并查集是一种用于管理元素所属集合的数据结构,实现为一个森林,其中每棵树表示一个集合,树中的节点表示对应集合中的元素。
顾名思义,并查集支持两种操作:

· 合并:合并两个元素所属集合。(合并对应的树)

· 查询:查询某个元素所属集合(查询对应的树的根节点),这可以用于判断两个元素是否属于同一集合。

更多用法可以看这里:OI-WIKI

代码

#include <bits/stdc++.h>
using namespace std;
int ans, p;
int K[100000];
int A[100000];
vector<int> v[10000];
void dfs(int n)
{
    p++;
    if (A[n] == 1)
        return;

    A[n] = 1;
    for (int i = 0; i < v[n].size(); i++)
    {
        if (A[v[n][i]] == 0)
        {
            dfs(v[n][i]);
        }
    }
}
int main()
{
    int n, i, r, m, k, a, b, c = 0, mp = 0;
    cin >> n >> m >> k;

    for (i = 0; i < k; i++)
    {
        cin >> K[i];
    }
    for (i = 0; i < m; i++)
    {
        cin >> a >> b;
        v[a].push_back(b);
        v[b].push_back(a);
    }

    for (i = 0; i < k; i++)
    {
        p = 0;
        dfs(K[i]);

        ans += (p * (p - 1)) / 2;
        mp = max(mp, p);
    }

    for (i = 1; i <= n; i++)
    {
        if (A[i] == 0)
        {
            c++;
        }
    }

    ans += ((mp + c) * (mp + c - 1)) / 2 - (mp * (mp - 1)) / 2;

    cout << ans - m;
}

posted @ 2023-10-04 09:00  _Unnamed  阅读(26)  评论(0)    收藏  举报