题目链接: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; }