Problem C

来源:互联网 发布:11.3非农数据预测 编辑:程序博客网 时间:2024/04/29 12:38

题意: 给出N个人, 每人会N[i]种语言, 问最少有人需要学多少种语言才能全部人可以沟通(两人间接能沟通就可以(通过里面的人翻译))

分析: 把有还有至少一种相同语言的人并在一起, 表示这个集合可以沟通, 答案就是  =  总集合 - 1,但是如果N个人都是一个语言也不会的话,答案就是N(特判)

算法: 并查集

#include <iostream>#include <cstdio>#include <queue>#include <cstring>#include <cmath>#include <vector>#include <set>#include <stack>#include <algorithm>//#include "myAlgorithm.h"#define MAX 1005#define INF 1e8#define eps 1e-5using namespace std;int n, m;int mp[MAX][MAX];int fa[MAX];void memset_fa(){    for(int i = 0; i <= n; i++){        fa[i] = i;    }}int find(int x){    if(x == fa[x])return x;    return fa[x] = find(fa[x]);}void merge(int faa, int fab){    if(faa != fab){        fa[faa] = fab;    }}int main(){   //freopen("in.txt", "w", stdout);    while(cin>>n>>m){        bool isAllZero = true;        for(int i = 1; i <= n; i++){            cin>>mp[i][0];            if(mp[i][0])isAllZero = false;            for(int j  = 1; j <= mp[i][0]; j++){                cin>>mp[i][j];            }        }///input end        if(isAllZero){//special judge            cout<<n<<endl;            continue;        }        memset_fa();       for(int i = 1; i <= n; i++){        for(int j = i + 1; j <= n; j++){            bool isFind = false;            for(int k = 1; k <= mp[i][0]; k++){                if(!isFind){                    for(int kk = 1; kk <= mp[j][0]; kk++){                        if(mp[i][k] == mp[j][kk]){                            isFind = true;                            break;                        }                    }                }               else                    break;            }            if(isFind){                int faa = find(i), fab = find(j);                merge(faa, fab);            }        }       }///solve end       set<int>setfa;       for(int i = 1; i <= n; i++){            setfa.insert(find(i));       }       int ans = setfa.size() - 1;       cout<<ans<<endl;    }    return 0;}