• tarjan——cogs 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

     

      1 #include<cstdio>
      2 #include<iostream>
      3 #include<cstring>
      4 #include<vector>
      5 #include<algorithm>
      6 
      7 #define M 200
      8 
      9 using namespace std;             
     10 
     11 int pp[M];
     12 int tk[M],top=0;          
     13 bool stk[M];            //标记点是否已在队列中 
     14 int dfn[M];             //记录点的标号 
     15 int low[M];             //记录点的最小上溯点位 
     16 int cnum=0;             //统计强连通分量个数 
     17 int dex=0;              //入队编号 
     18 vector <int> edge[M];   //储存边 
     19 int com[M][M];         //储存强连通分量(原来用的是动态数组,但是忘了动态数组怎么排序了……所以换成了二维数组) 
     20 int n;
     21 
     22 void input();
     23 void output();
     24 void tarjan(int);
     25 void chushihua();
     26 void jiaohuan(int,int);
     27 
     28 int main()
     29   {
     30       freopen("jdltt.in","r",stdin);
     31       freopen("jdltt.out","w",stdout);
     32       input();
     33       chushihua();
     34       output();
     35       fclose(stdin);fclose(stdout);
     36       return 0;
     37   }
     38 
     39 void input()
     40   {
     41       
     42       scanf("%d",&n);
     43       int a,b;
     44       while(scanf("%d%d",&a,&b)==2)
     45         {
     46             edge[a].push_back(b);
     47         }
     48   }
     49 
     50 void chushihua()                 //各种初始化…… 
     51   { 
     52       memset(tk,-1,sizeof(tk));
     53       memset(stk,0,sizeof(stk));
     54       memset(dfn,-1,sizeof(dfn));
     55       memset(low,-1,sizeof(low));
     56       for(int i=1;i<=n;i++)        //如果对该点还没入队过就跑一次tarjan 
     57         if(dfn[i]==-1)
     58           tarjan(i);
     59   }
     60 
     61 void tarjan(int i)
     62   {
     63       int j;
     64       dfn[i]=low[i]=dex++;         
     65       stk[i]=true;                 //入队标记 
     66       tk[++top]=i;                 //入队
     67       for(int e=0;e<edge[i].size();e++)       //遍历所有与该点相连的点 
     68         {
     69             j=edge[i][e];                      
     70             if(dfn[j]==-1)                      //情况一:点未入队——入队跑tarjan 
     71               {
     72                   tarjan(j);
     73                   low[i]=min(low[i],low[j]);
     74               }
     75         else
     76           if(stk[j]==1)                     //情况二:已入过对且正在队中 
     77             low[i]=min(low[i],dfn[j]);
     78         }
     79     if(dfn[i]==low[i])                      //强连通分量标识 
     80       {
     81           cnum++;
     82           do
     83             {
     84                 j=tk[top--];
     85 //                printf("%d ",j);
     86                 stk[j]=false;
     87                 com[cnum][0]++;
     88                 com[cnum][com[cnum][0]]=j;
     89             }
     90         while(j!=i);
     91       }
     92   }
     93 /*
     94 void jiaohuan(int a,int b)
     95   {
     96       memset(pp,0,sizeof(pp));
     97     int i=0;
     98     while(cc[a][i]!=0)
     99       {pp[i]=cc[a][i];i++;}
    100     memset(cc[a],0,sizeof(cc[a]));
    101     i=0;
    102     while(cc[b][i]!=0)
    103       cc[a][i]=cc[b][i],i++;
    104     memset(cc[b],0,sizeof(cc[b]));
    105     i=0;
    106     while(pp[i]!=0)
    107       cc[b][i]=pp[i],i++;
    108   }
    109 */
    110 
    111 void output()
    112   {
    113       printf("%d
    ",cnum);
    114       for(int k=1;k<=cnum;k++)            //先把每个强连通分量里的点按从小到大排序
    115                                         //(有智商的孩子就不要像我一样用冒泡排序了……) 
    116         {
    117             int p=com[k][0];
    118             for(int i=1;i<=p;i++)
    119               for(int j=i+1;j<=p;j++)
    120                 if(com[k][i]>com[k][j])
    121                   {
    122                       int b=com[k][i];
    123                       com[k][i]=com[k][j];
    124                       com[k][j]=b;
    125                   }
    126         }
    127     for(int i=1;i<=cnum;i++)           //把强连通分量按首的大小从小到大排序,依旧是冒泡…… 
    128       for(int j=i+1;j<=cnum;j++)
    129         if(com[i][1]>com[j][1])        //我的com[i][0]储存的是第i个强连通分量包含几个点 
    130           {
    131               memset(pp,0,sizeof(pp));
    132               for(int k=0;k<=com[i][0];k++)
    133                 pp[k]=com[i][k];
    134               for(int k=0;k<=com[j][0];k++)
    135                 com[i][k]=com[j][k];
    136               for(int k=0;k<=pp[0];k++)
    137                 com[j][k]=pp[k];
    138           }
    139       for(int i=1;i<=cnum;i++)          //真正的输出过程…… 
    140         {
    141             for(int j=1;j<=com[i][0];j++)
    142               printf("%d ",com[i][j]);
    143             printf("
    ");
    144         }
    145   }
    tarjan
  • 相关阅读:
    解决tomcat CNTA-2020-0004漏洞
    简单理解程序如何控制硬件的
    【Spring】Spring Session的简单搭建与源码阅读
    【Spring】Spring,我的零散使用杂记
    CORS跨域、Cookie传递SessionID实现单点登录后的权限认证的移动端兼容性测试报告
    【Fiddler】Fiddler抓包
    一起学习Maven
    分布式系统接口调用回滚方案
    【FastDFS】FastDFS在CentOS的搭建
    【Java】Java日志框架Logback的简单例子
  • 原文地址:https://www.cnblogs.com/yuemo/p/5494562.html
Copyright © 2020-2023  润新知