Codeforces 745C 并查集+贪心

来源:互联网 发布:网络信息员岗位职责 编辑:程序博客网 时间:2024/05/07 21:14

点击打开链接

//题意:n个定点 m条边(无重边),有k个顶点之间不能有路径存在,问最多能添加多少条边时,仍然满足情况 
//因为k个顶点之间不能有路径存在 则最后图中剩下的联通分量个数为k

//显然最后组成的最大的哪一个联通分量,点数要尽可能的多,其余有限制的联通分量里面的边数是size*(size-1)/2

#include <bits/stdc++.h>using namespace std;typedef long long ll;typedef pair<ll,ll> P;const int inf=1e9;const int N=2e3+20;const int M=2e3+20;int n,m,k,c[N];int fa[N],size[N],rank[N];// int find(int x){if(fa[x]!=x){fa[x]=find(fa[x]);}return fa[x];}void Union(int fx,int fy){fa[fx]=fy;size[fy]+=size[fx];if(rank[fx])rank[fy]=1;//该联通分量包含元素c[i] }int main(){while(cin>>n>>m>>k){for(int i=1;i<=n;i++){fa[i]=i;size[i]=1;rank[i]=0;} for(int i=1;i<=k;i++){scanf("%d",&c[k]);rank[c[k]]=1;}for(int i=0;i<m;i++){int u,v;scanf("%d%d",&u,&v);if(find(u)!=find(v)){Union(find(u),find(v));}}int ans=0,cnt=0,num=0;bool flag=false;for(int i=1;i<=n;i++){if(fa[i]==i){if(rank[i]==0)cnt+=size[i];//这些没限制的可以合成一个联通分量 else{num=max(num,size[i]);//有限制的 取一个最大的即可于无限制的组合 ans+=(size[i]*(size[i]-1))/2; // }}}ans-=num*(num-1)/2;cnt+=num;//找到最后最大的联通分类能包含多少个点 ans+=cnt*(cnt-1)/2-m;cout<<ans<<endl;}return 0;} 


0 0
原创粉丝点击