zoukankan      html  css  js  c++  java
  • 【uva 247】Calling Circles(图论--Floyd 传递闭包+并查集 连通分量)

    题意:有N个人互相打了M次电话,请找出所有电话圈(Eg.a→b,b→c,c→d,d→a 就算一个电话圈)并输出。(N≤25,L≤25,注意输出格式)

    解法:由于N比较小所有n^2或n^3的复杂度都没有问题。所以就O(n^2)读入;O(n^3)Floyd算法求出传递闭包,d[i][j]表示 i 是否直接或间接给 j 打过电话,并查集并起一个电话圈里的人;O(n^2)输出。总的是O(n^3)的时间复杂度。

    P.S.我的代码有点长~再补个连通分量和强连通分量的知识:连通分量——强连通图的连通分量为其本身。如果为非连通图,则连通分量为该图的最大连通子图;有向图强连通分量——在有向图G中,如果两个顶点vi,vj间(vi>vj)有一条从vi到vj的有向路径,同时还有一条从vj到vi的有向路径,则称两个顶点强连通(strongly connected)。如果有向图G的每两个顶点都强连通,称G是一个强连通图。有向图的极大强连通子图,称为强连通分量(strongly connected components)。

     1 #include<cstdio>
     2 #include<cstdlib>
     3 #include<cstring>
     4 #include<iostream>
     5 using namespace std;
     6 
     7 const int N=27,M=910;
     8 int n,m,T=0;
     9 int d[N][N],fa[N];
    10 char s[N],ss[N],str[N][N];
    11 
    12 void input()
    13 {
    14     int x,y,len=0;
    15     memset(d,0,sizeof(d));
    16     for (int i=1;i<=m;i++)
    17     {
    18       scanf("%s%s",s,ss);
    19       x=y=0;
    20       for (int j=1;j<=len;j++)
    21       {
    22         if (!strcmp(s,str[j])) x=j;
    23         if (!strcmp(ss,str[j])) y=j;
    24       }
    25       if (!x) memcpy(str[++len],s,sizeof(s)),x=len;
    26       if (!y) memcpy(str[++len],ss,sizeof(ss)),y=len;
    27       d[x][y]=1;
    28     }
    29 }
    30 int ffind(int x)
    31 {
    32     if (fa[x]!=x) fa[x]=ffind(fa[x]);
    33     return fa[x];
    34 }
    35 void solve()
    36 {
    37     for (int k=1;k<=n;k++)
    38      for (int i=1;i<=n;i++)
    39       for (int j=1;j<=n;j++)
    40         d[i][j]=d[i][j]|(d[i][k]&d[k][j]);
    41 
    42     for (int i=1;i<=n;i++) fa[i]=i;
    43     for (int i=1;i<=n;i++)
    44      for (int j=1;j<=n;j++)
    45      {
    46        if (!d[i][j] || !d[j][i]) continue;
    47        int fx=ffind(i),fy=ffind(j);
    48        if (fx!=fy) fa[fx]=fy;
    49      }
    50     if (T) printf("
    ");
    51     printf("Calling circles for data set %d:
    ",++T);
    52     for (int i=1;i<=n;i++)
    53     {
    54       if (fa[i]!=i) continue;
    55       printf("%s",str[i]);
    56       for (int j=1;j<=n;j++)
    57         if (fa[j]==i && i!=j) printf(", %s",str[j]);
    58       printf("
    ");
    59     }
    60 }
    61 int main()
    62 {
    63     while (1)
    64     {
    65       scanf("%d%d",&n,&m);
    66       if (!n && !m) break;
    67       input();
    68       solve();
    69     }
    70     return 0;
    71 }
  • 相关阅读:
    CSRF跨站请求伪造
    FineReport 导出汉字乱码
    Java 程序中中文没有乱码,存入数据库后中文乱码问题
    分析函数
    Redis的持久化与主从复制
    分布式Redis的使用
    redis的介绍和安装
    Solr后台管理及SolrJ的使用
    Solr总结
    bootstrap 点击回到顶部 超简单
  • 原文地址:https://www.cnblogs.com/konjak/p/6036091.html
Copyright © 2011-2022 走看看