Codeforces Round #385 (Div. 2) C

题目链接:http://codeforces.com/contest/745/problem/C

题意:给出n个点m条边,还有k个不能连通的点,问最多能添加几条边。

要知道如果有n个点最多的边是n*(n-1),显然最多的边就是构成一个完全图但是由于有k个点不能连通,

所以先处理一下与k个点链接的几个点,然后再在k个点中选出包含点最多的然后把剩余的点全都与这个

点链接,最后减去m边即可。

#include <iostream>
#include <cstring>
#include <vector>
#include <algorithm>
using namespace std;
const int M = 1e5 + 10;
int a[M] , b[M] , gg;
bool vis[M];
vector<int>vc[M];
bool cmp(int x , int y) {
    return x > y;
}
void dfs(int pos) {
    vis[pos] = 1;
    gg++;
    int len = vc[pos].size();
    for(int i = 0 ; i < len ; i++) {
        if(!vis[vc[pos][i]]) {
            vis[vc[pos][i]] = true;
            dfs(vc[pos][i]);
        }
    }
}
int main() {
    int n , m , k;
    cin >> n >> m >> k;
    for(int i = 0 ; i < k ; i++) {
        cin >> a[i];
    }
    for(int i = 0 ; i < m ; i++) {
        int x , y;
        cin >> x >> y;
        vc[x].push_back(y);
        vc[y].push_back(x);
    }
    int count = 0;
    int sum = 0;
    memset(vis , false , sizeof(vis));
    for(int i = 0 ; i < k ; i++) {
        vis[a[i]] = true;
        gg = 0;
        dfs(a[i]);
        b[i] = gg;
        sum += b[i];
    }
    sort(b , b + k , cmp);
    b[0] += (n - sum);
    for(int i = 0 ; i < k ; i++) {
        count += (b[i] * (b[i] - 1)) / 2;
    }
    count -= m;
    cout << count << endl;
    return 0;
}
原文地址:https://www.cnblogs.com/TnT2333333/p/6193697.html