BZOJ——3296: [USACO2011 Open] Learning Languages
http://www.lydsy.com/JudgeOnline/problem.php?id=3296
Time Limit: 5 Sec Memory Limit: 128 MB
Submit: 254 Solved: 134
[Submit][Status][Discuss]
Description
农夫约翰的N(2 <= N<=10,000)头奶牛,编号为1.. N,一共会流利地使用M(1<= M <=30,000)种语言,编号从1 .. M.,第i头,会说K_i(1 <= K_i<= M)种语言,即L_i1, L_i2,..., L_{iK_i} (1 <= L_ij <= M)。 FJ的奶牛不太聪明,所以K_i的总和至多为100,000。
两头牛,不能直接交流,除非它们都会讲某一门语言。然而,没有共同语言的奶牛们,可以让其它的牛给他们当翻译。换言之,牛A和B可以谈话,当且仅当存在一个序列奶牛T_1,T_2,...,T_k,A和T_1都会说某一种语言,T_1和T_2也都会说某一种语言……,并且T_k和B会说某一种语言。
农夫约翰希望他的奶牛更加团结,所以他希望任意两头牛之间可以交流。他可以买书教他的奶牛任何语言。作为一个相当节俭的农民,FJ想要购买最少的书籍,让所有他的奶牛互相可以说话。
帮助他确定:
*他必须购买的书籍的最低数量
Input
*第1行:两个用空格隔开的整数:N和M
*第2.. N +1行:第i +1行描述的牛i的语言,K_i+1个空格隔开的整数:K_i L_i1
L_i2,...,L_I{K_i}。
Output
*第1行:一个整数,FJ最少需要购买的书籍数量。
Sample Input
3 3
2 3 2
1 2
1 1
2 3 2
1 2
1 1
Sample Output
1
HINT
给三号牛买第二本书即可
Source
把会相同语言的牛合并到同一个并查集里,ans=并查集数-1
1 #include <cstdio> 2 3 inline void read(int &x) 4 { 5 x=0; register char ch=getchar(); 6 for(; ch>'9'||ch<'0'; ) ch=getchar(); 7 for(; ch>='0'&&ch<='9'; ch=getchar()) x=x*10+ch-'0'; 8 } 9 const int M(30005); 10 const int N(10005); 11 int n,m,ans,fa[N],bel[M]; 12 13 int find(int x) { return x==fa[x]?x:fa[x]=find(fa[x]); } 14 15 int Presist() 16 { 17 read(n),read(m); 18 for(int i=1; i<=n; ++i) fa[i]=i; 19 for(int t,fx,i=1; i<=n; ++i) 20 { 21 read(t);fx=find(i); 22 for(int x,fy; t--; ) 23 { 24 read(x); 25 if(bel[x]) 26 { 27 fx=find(i),fy=find(bel[x]); 28 if(fx!=fy) fa[fx]=fy; 29 } 30 else bel[x]=i; 31 } 32 } 33 for(int i=1; i<=n; ++i) ans+=(find(i)==i); 34 printf("%d\n",ans-1); 35 return 0; 36 } 37 38 int Aptal=Presist(); 39 int main(int argc,char**argv){;}
——每当你想要放弃的时候,就想想是为了什么才一路坚持到现在。