Codeforces Round #170 (Div. 2) C. Learning Languages【并查集】
http://codeforces.com/problemset/problem/278/C
一开始一门语言都不会的肯定都需要辅导其一门语言,会语言的用并查集处理,一共有几个集合,就辅导几减一的人。
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <vector> #include <set> #include <map> #include <cmath> #include <queue> using namespace std; template <class T> void checkmin(T &t,T x) {if(x < t) t = x;} template <class T> void checkmax(T &t,T x) {if(x > t) t = x;} template <class T> void _checkmin(T &t,T x) {if(t==-1) t = x; if(x < t) t = x;} template <class T> void _checkmax(T &t,T x) {if(t==-1) t = x; if(x > t) t = x;} typedef pair <int,int> PII; typedef pair <double,double> PDD; typedef long long ll; #define foreach(it,v) for(__typeof((v).begin()) it = (v).begin(); it != (v).end ; it ++) const int N = 110; int f[N] , langnum[N] , n , m; int a1 , a2; bool g[N][N]; int find(int x) { return x==f[x] ? x : f[x] = find(f[x]); } void Union(int x,int y) { int a = find(x) , b = find(y); f[a] = f[b] = f[x] = f[y] = min(a , b); } bool check(int u,int v) { for(int i=1;i<=m;i++) if(g[u][i] && g[v][i]) return true; return false; } bool vis[N]; int main() { a1 = 0; a2 = -1; cin >> n >> m; for(int i=1;i<=n;i++) f[i] = i; for(int i=1;i<=n;i++) { cin >> langnum[i]; if(langnum[i] == 0) a1 ++; for(int j=0;j<langnum[i];j++) { int a; cin >> a; g[i][a] = 1; } } for(int i=1;i<=n;i++) if(langnum[i]) for(int j=i+1;j<=n;j++) if(langnum[j]) if(check(i , j)) Union(i , j); for(int i=1;i<=n;i++) { if(langnum[i] == 0) continue; int ii = find(i); if(!vis[ii]) { vis[ii] = 1; a2 ++; } } if(a2 == -1) a2 ++; cout <<a1+a2<<endl; return 0; }