【POJ】[1611]The Suspects

来源:互联网 发布:最长公共子序列c语言 编辑:程序博客网 时间:2024/04/28 08:10

这里写图片描述
输入输出

上次个人赛出了这一题
不过当时用的搜索的思维来写的

大概就是遇见一个人感染
则寻找所有社团中包含这个人的社团
并分别对每一个成员递归

#include<stdio.h>#include<string.h>int n,z,cnt;int a[500][1000];int b[30000];void s(int m) {    if(!b[m]) {        cnt++;        b[m]=1;    } else        return ;    for(int i=0; i<z; i++) {        for(int j=1; j<=a[i][0]; j++) {            if(a[i][j]==m) {                for(int k=1; k<=a[i][0]; k++) {                    if(a[i][k]!=m)                        s(a[i][k]);                }                break;            }        }    }}int main() {    while(scanf("%d %d",&n,&z),n!=0||z!=0) {        memset(b,0,sizeof(b));        memset(a,0,sizeof(a));        for(int i=0; i<z; i++) {            scanf("%d",&a[i][0]);            for(int j=1; j<=a[i][0]; j++) {                scanf("%d",&a[i][j]);            }        }        cnt=0;        s(0);        printf("%d\n",cnt);    }    return 0;}

不过这一题用并查集的思想还是更为简便一些

也就是直接根据社团关系来合并集合
然后最后查找有几个和 0 号在同一个集合

#include<stdio.h>int par[30200];int rank[30200];int find(int m) {    if(m==par[m])        return m;    else        return par[m]=find(par[m]);}void unite(int x,int y) {    x=find(x);    y=find(y);    if(x==y)        return;    if(rank[x]<rank[y])        par[x]=y;    else {        par[y]=x;        if(rank[x]==rank[y])            rank[x]++;    }}int main() {    int n,m;    while(scanf("%d %d",&n,&m),n||m) {        for(int i=0; i<n; i++) {            par[i]=i;            rank[i]=0;        }        for(int i=0; i<m; i++) {            int k;            scanf("%d",&k);            int t;            scanf("%d",&t);            k--;            while(k--) {                int p;                scanf("%d",&p);                unite(t,p);                t=p;            }        }        int cnt=0;        for(int i=0; i<n; i++) {            if(find(i)==find(0))                cnt++;        }        printf("%d\n",cnt);    }    return 0;}

题目地址:【POJ】[1611]The Suspects

0 0
原创粉丝点击