zoukankan      html  css  js  c++  java
  • 1298. 通讯问题

    1298. 通讯问题

    ★   输入文件:jdltt.in   输出文件:jdltt.out   简单对比
    时间限制:1 s   内存限制:128 MB

    【题目描述】

    一个篮球队有n个篮球队员,每个队员都有联系方式(如电话、电子邮件等)。但并不是每个队员的联系方式都公开,每个队员的联系方式只有一部分队员知道。问队员可以分成多少个小组,小组成员之间可以相互通知(包括一个队员一个组,表示自己通知自己)。

    【输入格式】

    输入文件有若干行

    第一行,一个整数n,表示共有n个队员(2<=n<=100)

    下面有若干行,每行2个数a、b,a、b是队员编号,表示a知道b的通讯方式。

    【输出格式】

    输出文件有若干行

    第一行,1个整数m,表示可以分m个小组,下面有m行,每行有若干个整数,表示该小组成员编号,输出顺序按编号由小到大。

    【样例输入】

    12
    1 3
    2 1
    2 4
    3 2
    3 4
    3 5
    4 6 
    5 4
    6 4
    7 4
    7 8
    7 12
    8 7
    8 9
    10 9
    11 10

    【样例输出】

    8

    1 2 3

    4 6

    5

    7 8

    9

    10

    11

    12

    暴力代码

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    using namespace std;
    int n,m,k,x,y;
    #define N 110
    int a[N][N],b[N/2][N],vis[N],jl[N],zj=0,tot=0,t1=0,qi;
    void bj(int z){
        for(int i=0;i<zj;i++)
           vis[jl[i]]=1;
        sort(jl,jl+zj);
        zj=unique(jl,jl+zj)-jl;
        for(int i=0;i<zj;i++)
          b[jl[0]][i]=jl[i];
        tot++;
        for(int i=0;i<zj;i++) jl[i]=0;
        zj=0;
    }
    void dfs(int u,int v){
        if(vis[u]||vis[v]||u==v) return;
        if(v==qi) {bj(zj); return;}
        if(a[u][v]&&!vis[v]) {
            jl[zj++]=v;
            for(int j=1;j<=n;j++){
                if(a[v][j]&&!vis[j])
                  dfs(v,j);
            }
        }
        if(u==qi&&zj>0) zj--;
    }
    int main()
    {
        freopen("jdltt.in","r",stdin);
        freopen("jdltt.out","w",stdout);
        scanf("%d",&n);
        while(scanf("%d%d",&x,&y)==2){
            a[x][y]=1;
        }
        for(qi=1;qi<=n;qi++){
            for(int j=1;j<=n;j++)
            if(qi!=j&&a[qi][j]){
               if(!vis[qi]){
                     if(!vis[j]){
                         jl[zj++]=qi;
                    dfs(qi,j);
                    }else continue; 
               }else break;
               
            }
        }
        for(int i=1;i<=n;i++) 
           if(!vis[i]) t1++;
        printf("%d
    ",t1+tot);
        for(int i=1;i<=n;i++){
            if(b[i][0]!=0){
                for(int j=0;b[i][j];j++){
                    printf("%d ",b[i][j]);
                }
                printf("
    ");
            }
            else if(!vis[i])
                    printf("%d
    ",i);
            
        }
        return 0;
    }

     暴力代码虽然ac(数据太水),但有bug;

    例如

    输入数据
    5
    1 2
    2 3
    3 1
    2 4
    4 5
    5 1
    
    正确输出
    1
    1 2 3 4 5

    然而 不对;

    正确tarjan算法:(一样ac)

    #include<cstdio>
    #include<iostream>
    #include<vector>
    #include<stack>
    #include<algorithm>
    #define M 100010
    #define N 2010
    using namespace std;
    vector<int> grap[M];
    stack<int> s;
    int low[M],num[M],vis[M],instack[M];
    int index,cnt,n;
    struct node{
        int sum;
        int dl[N];
        void px()
        {
            sort(dl+1,dl+sum+1);
        }
    };node f[N];
    int cmp(const node&x,const node&y)
    {
        return x.dl[1]<y.dl[1];
    }
    void tarjan(int v)
    {
        low[v]=num[v]=++index;
        s.push(v);
        instack[v]=1;
        vis[v]=1;
        for(int i=0;i<grap[v].size();i++){
            int w=grap[v][i];
            if(!vis[w]){
                tarjan(w);
                low[v]=min(low[v],low[w]);
            }
            else if(instack[w])
              low[v]=min(low[v],num[w]);
        }
        int u;
        if(low[v]==num[v]){
            ++cnt;
            do
            {
                u=s.top();
                f[cnt].dl[++f[cnt].sum]=u;
                s.pop();
                instack[u]=0;
            }while(u!=v);
        }
    }
    int main()
    {
        freopen("jdltt.in","r",stdin);
        freopen("jdltt.out","w",stdout);
        int x,y;
        scanf("%d",&n);
        while(scanf("%d%d",&x,&y)==2)
           grap[x].push_back(y);
        for(int i=1;i<=n;i++)
           if(!vis[i])tarjan(i);
        printf("%d
    ",cnt);
        for(int i=1;i<=cnt;i++)
           f[i].px();
        sort(f+1,f+cnt+1,cmp);
        for(int i=1;i<=cnt;i++){
            for(int j=1;j<=f[i].sum;j++)
               printf("%d ",f[i].dl[j]);
            printf("
    ");
        }
        return 0;
    }
  • 相关阅读:
    java自定义注解教程
    java8 LocalDateTime时间格式化
    java8新特性Stream用法详解
    java将数组转换成list集合
    elestaticsearch原生写法创建mapping
    springboot-mybatis-plus生成器
    jQuery.bind() 函数详解
    CSS3 中的 rem 值与 px 之间的换算
    console.log的应用
    JQuery中$(document)是什么意思有什么作用
  • 原文地址:https://www.cnblogs.com/shenben/p/5495887.html
Copyright © 2011-2022 走看看