1. 程式人生 > >CodeForces 745C Hongcow Builds A Nation 並查集

CodeForces 745C Hongcow Builds A Nation 並查集

pre its scan 思路 max 城市 define tor 博客

題意:

給了你n個城市 m條邊 k個政府

每個政府管轄的區域內不能和其他政府的區域有相連

即政府之間不存在路徑

問你在維護這種關系的同時

最多再加多少條邊

思路:

先找出來每個聯通塊

再找出來沒有歸屬的孤立的點

把他們都放到最大的聯通塊裏

然後每個聯通塊之間的點兩兩連邊是n*(n-1)/2條邊

最後算出來的ans-m就好了

(看別人的博客學了一個max_element

 1 #include<bits/stdc++.h>
 2 #define cl(a,b) memset(a,b,sizeof(a))
 3 #define debug(a) cerr<<#a<<"=="<<a<<endl
 4
using namespace std; 5 typedef long long ll; 6 typedef pair<int,int> pii; 7 8 const int maxn=1e5+10; 9 10 int fa[maxn]; 11 12 int fd(int i) 13 {//並查集 14 if(fa[i]==0) return i; 15 else return fa[i]=fd(fa[i]); 16 } 17 18 int main() 19 { 20 int n,m,k; 21 scanf("
%d%d%d",&n,&m,&k); 22 vector<int>vis(n+1,0); 23 vector<int>gov(k,0),num(k,0); 24 for(int i=0;i<k;i++) 25 { 26 scanf("%d",&gov[i]); 27 } 28 for(int i=0;i<m;i++) 29 { 30 int x,y; 31 scanf("%d%d",&x,&y);
32 int fx=fd(x),fy=fd(y); 33 if(fx!=fy) 34 {//如果不相連的話 把兩個點相連 35 fa[fx]=fy; 36 } 37 38 } 39 for(int i=1;i<=n;i++) 40 {//尋找每個節點所在聯通塊的大小 41 vis[fd(i)]++; 42 } 43 int rest=n;//初始化所有的點都剩下了 44 for(int i=0;i<k;i++) 45 {//最每個政府所在聯通塊大小進行記錄 46 num[i]=vis[fd(gov[i])]; 47 rest-=num[i];//減去已經記錄過的點 48 } 49 //剩下的rest就是孤立的點的個數 50 51 ///新姿勢 找出最大的聯通塊 52 auto mx=max_element(num.begin(),num.end()); 53 ///max_element類似於kdtree模板中的nth_element 54 55 *mx+=rest;//把剩下的點放到最大的連通塊中 56 int sum=0; 57 for(auto i:num) 58 { 59 sum+=i*(i-1)/2; 60 } 61 printf("%d\n",sum-m); 62 return 0; 63 }/* 64 65 3 3 1 66 2 67 1 2 68 1 3 69 2 3 70 71 */

CodeForces 745C Hongcow Builds A Nation 並查集