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;
}

 

posted @ 2013-03-30 23:56  aiiYuu  阅读(149)  评论(0编辑  收藏  举报