n个人,每个人会一些语言,两个人只要有会一门相同的语言就可以交流,问为了让这n个人都交流,至少还得学多少门语言
先根据n个人之间他们会的语言,建边
再dfs找出有多少个联通块ans,再加ans-1条边就可以让他们连通
注意特判一下每个人都会0门语言的情况
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 #include<vector> 6 using namespace std; 7 8 const int maxn = 105; 9 int g[maxn][maxn],a[maxn][maxn]; 10 int vis[maxn]; 11 int n,m; 12 13 void dfs(int u){ 14 vis[u] = 1; 15 for(int v = 1;v <= n;v++){ 16 if(!vis[v] && g[u][v]) dfs(v); 17 } 18 } 19 20 int main(){ 21 int ans = 0; 22 scanf("%d %d",&n,&m); 23 memset(g,0,sizeof(g)); 24 memset(a,0,sizeof(a)); 25 int tot = 0; 26 for(int u = 1;u <= n;u++){ 27 int k; 28 scanf("%d",&k); 29 if(k == 0) tot++; 30 for(int i = 0;i < k;i++){ 31 int v; 32 scanf("%d",&v); 33 a[u][v] = 1; 34 } 35 } 36 37 if(tot == n) printf("%d ",tot); 38 else { 39 for(int u = 1;u <= n;u++){ 40 for(int v = u+1;v <= n;v++){ 41 for(int k = 1;k <= m;k++){ 42 if(a[u][k] && a[v][k]) g[u][v] = g[v][u] = 1; 43 } 44 } 45 } 46 47 for(int i = 1;i <= n;i++) { 48 if(!vis[i]){ 49 ans++; 50 dfs(i); 51 } 52 } 53 printf("%d ",ans-1); 54 } 55 return 0; 56 }