标签:initial 一个 limit present idt sub pre iostream data
Time Limit: 1000MS | Memory Limit: 20000K | |
Total Submissions: 21427 | Accepted: 10375 |
Description
Input
Output
Sample Input
100 4 2 1 2 5 10 13 11 12 14 2 0 1 2 99 2 200 2 1 5 5 1 2 3 4 5 1 0 0 0
Sample Output
4 1 1
题意:n,表示学生数目, m,表示社团数目。 每一个学生有一个编号。 0到N-1。 编号为0的学生是全部学生中最初的唯一感染者, 接下来由m个社团, 在每行输入一个k
,k表示社团的总人数, 接着是社团中k个成员的编号。
。 当输入n=0且m=0时,输入结束。
。
输出被感染的总人数。
。
解题思路:
本题编号为0的人已经被感染了,所以被感染的人数至少为1
运用并查集划分集合的同一时候记录每个集合 的元素个数。。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<vector> #include<queue> #include<sstream> #include<cmath> using namespace std; #define f1(i, n) for(int i=0; i<n; i++) #define f2(i, n) for(int i=1; i<=n; i++) #define f3(i, n) for(int i=n; i>=1; i--) #define f4(i, n) for(int i=2; i<=n; i++) #define M 30050 int n; int p[M]; int r[M]; int a[M]; void start() { for(int i=0; i<=n-1; i++) { p[i]=i; //初始化并查集 r[i]=1; //初始化时,每一个元素作为一个集合,其元素为1 } } int find(int x) //并查集的find { return p[x] == x ? x : p[x] = find ( p[x] ); } void Kruskal(int x, int y) { int xx = find(x); int yy = find(y); //找出当前两个端点所在集合的编号 //假设在不同集合就合并 if(xx!=yy) { r[xx] += r[yy]; //合并时更改集合元素的总数 p[yy] = xx; } } int main() { int m; while(scanf("%d%d",&n,&m)!=EOF) { if(n==0 && m==0) break; start(); while( m-- ) { int t; scanf("%d", &t); f1(i, t) { scanf("%d", &a[i]); if(i!=0) Kruskal(a[i-1], a[i]); } } printf("%d\n", r[find(0)]);//找到包括0元素的集合的节点。并输出其记录的节点数目 } return 0; }
标签:initial 一个 limit present idt sub pre iostream data
原文地址:http://www.cnblogs.com/yutingliuyl/p/7225234.html