并查集 的几题典型题以及代码

    xiaoxiao2021-03-25  150

     

    题目:https://www.cnblogs.com/Sunshine-tcf/p/5699059.html

    #include <iostream> #include <stdio.h> #include <algorithm> #include <string> using namespace std; int p[1005]; int find(int x) {      if(x==p[x]) return x;     else return (p[x]=find(p[x])); } void inin(int n) {     for(int i=1;i<=n;i++)     {         p[i]=i;     } } void unions(int x,int y) {     int j,k;     j=find(x);     k=find(y);     p[j]=k; } int main() {     int T;     while(cin>>T)     {         while(T--)         {             int m,n,i,j;             cin>>m>>n;             inin(m);             for(i=0;i<n;i++)             {                 int a,b;                 cin>>a>>b;                 unions(a,b);             }             int k=0;             for(i=1;i<=m;i++)             {                 if(i==p[i])                 {                     k++;                 }             }             cout<<k<<endl;         }     }     return 0; }

    5-16 朋友圈   (25分)

    某学校有N个学生,形成M个俱乐部。每个俱乐部里的学生有着一定相似的兴趣爱好,形成一个朋友圈。一个学生可以同时属于若干个不同的俱乐部。根据“我的朋友的朋友也是我的朋友”这个推论可以得出,如果A和B是朋友,且B和C是朋友,则A和C也是朋友。请编写程序计算最大朋友圈中有多少人。

    输入格式:

    输入的第一行包含两个正整数N(\le≤30000)和M(\le≤1000),分别代表学校的学生总数和俱乐部的个数。后面的M行每行按以下格式给出1个俱乐部的信息,其中学生从1~N编号:

    第i个俱乐部的人数Mi(空格)学生1(空格)学生2 … 学生Mi

    输出格式:

    输出给出一个整数,表示在最大朋友圈中有多少人。

    输入样例:

    7 4 3 1 2 3 2 1 4 3 5 6 7 1 6

    输出样例:

    4 #include <cstdio> #include <cstdlib> #include <cstring> #include <map> using namespace std; const int maxx = 30002; int pre[maxx]; map<int,int> mp; void init(int n) { int i; for(i=1;i<=n;++i){ mp[i] = 0; pre[i] = i; } } int root(int x){ if(x!=pre[x]){ pre[x] = root(pre[x]); } return pre[x]; } void merge(int x,int y){ if(y==-1)return; int fa = root(x); int fb = root(y); if(fa!=fb){ pre[fa] = fb; } } int main(){ int n,m,mi,i,j,a,pre,fa; while(scanf("%d %d",&n,&m)!=EOF){ init(n); mp.clear(); for(i=0;i<m;++i){ pre = -1; scanf("%d",&mi); for(j=0;j<mi;++j){ scanf("%d",&a); merge(a,pre); pre = a; } } int maxx = -1; for(i=1;i<=n;++i){ fa = root(i); ++mp[fa]; if(mp[fa]>maxx)maxx = mp[fa]; } printf("%d\n",maxx); } return 0; }

     

    忍者村是忍者聚居的村子,相等于国家的军事力量。绝大部分村民都是忍者,有一些忍者会在村内开设书店、餐厅等,不过大部分忍者都是为村子执行任务的忍者,以赚取酬劳,并于战时为国家出战。村子亦会培训年轻村民成为忍者。

    忍者们一般以三人一组执行各种任务,现在假设不同村子的忍者不会一起执行任务,给出一些忍者的组合,判断由这些组合能确定的最多的忍者村的个数。

    Input

    第一行是整数n,表示已知n组忍者组合,接下来n行每行三个忍者的名字,n不超过1000,每个名字不长于10.

    Output

    对于每组输入,输出在这些忍者最多属于多少个忍者村。

    Sample Input

    7

    a b c

    c d e

    d e f

    g k h

    l m n

    o p q

    h r p

    Sample Output

    3

     

    #include<stdio.h> #include<iostream> #include<map> #include<string.h> using namespace std; int p[3005]; void init(int t) {     for(int i=0;i<=t*3;i++)     p[i]=i; } int find(int x) {     return p[x] == x ? x : (p[x] = find(p[x])); } void merge(int a,int b) {     int A,B;     A=find(a);     B=find(b);     if(A!=B)     p[B]=A; } int main() {     int t;     while(~scanf("%d",&t))     {         map<string,int>a;         int z=1;         init(t);         for(int i=0;i<t;i++)         {             char b[3][20];             for(int j=0;j<3;j++)             {                 scanf("%s",b[j]);                 if(a[b[j]]==0){a[b[j]]=z;z++;}             }             merge(a[b[0]],a[b[1]]);             merge(a[b[0]],a[b[2]]);         }         int ans=0;         for(int i=0;i<z;i++)         {             if(i==p[i])ans++;         }         printf("%d\n",ans-1);     }     return 0; }

     

    转载请注明原文地址: https://ju.6miu.com/read-4865.html

    最新回复(0)