题目大意:中文题不多说了
题目思路:将每一个可能患病的人纳入同一个集合,然后遍历查找每个点,如果改点点的根节点和0号学生的根节点相同,则该点可能是病人。
模板题并没有思路上的困难,只不过在遍历时需要额外注意一点,避免超时,具体看代码吧
#include<cstdio> #include<cstdlib> #include<cmath> #include<iostream> #include<algorithm> #include<cstring> #include<vector> #include<queue> #define INF 0x3f3f3f3f #define MAX 1000005 using namespace std; int father[MAX],a[MAX]; int Find(int k) { while(k!=father[k]) { k=father[k]; } return k; } int main() { int n,m,k,i,j,ans,a,b,sum; while(scanf("%d%d",&n,&m),n||m) { sum=0; for(i=0;i<n;i++) father[i]=i; for(i=1;i<=m;i++) { scanf("%d%d",&k,&a); for(j=1;j<k;j++) { scanf("%d",&b); int x=Find(a); int y=Find(b); if(x!=y) { father[y]=x; } } } int ans=Find(0);//为了节省时间,在循环外求出Find(0),不然会超时。 for(i=0;i<n;i++) { if(ans==Find(i)) sum++; } printf("%d ",sum); } return 0; }