• UVA 247"Calling Circles"(floyd求传递闭包+SCC)


    传送门

    题意:

      如果两个人相互打电话(直接或间接),则说他们在同一个电话圈里。

      (a,b) 表示 a 打给 b;

      例如,(a,b),(b,c),(c,d),(d,a),则这四个人在同一个电话圈里;

      输入 n(n≤25) 个人的 m 次电话,找出所有的电话圈,输出每个电话圈里的人名(无序)。

    题解:

      首先用floyd求出传递闭包,构造新图;

      然后在新图上跑一遍SCC求解;

    AC代码:

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 #define memF(a,b,n) for(int i=0;i <= n;a[i]=b,++i);
      4 const int maxn=30;
      5 
      6 int n,m;
      7 int num;
      8 int head[maxn];
      9 struct Edge
     10 {
     11     int to;
     12     int next;
     13 }G[maxn*maxn*2];
     14 void addEdge(int u,int v)
     15 {
     16     G[num]={v,head[u]};
     17     head[u]=num++;
     18 }
     19 map<string ,int >f;
     20 map<int ,string >g;
     21 bitset<maxn>_bit[maxn];
     22 int col[maxn];
     23 struct SCC
     24 {
     25     vector<int >vs;
     26     bool vis[maxn];
     27     void DFS(int u)
     28     {
     29         vis[u]=true;
     30         for(int i=head[u];~i;i=G[i].next)
     31         {
     32             int v=G[i].to;
     33             if(vis[v] || (i&1))
     34                 continue;
     35             DFS(v);
     36         }
     37         vs.push_back(u);
     38     }
     39     void RDFS(int u,int k)
     40     {
     41         vis[u]=true;
     42         col[u]=k;
     43         for(int i=head[u];~i;i=G[i].next)
     44         {
     45             int v=G[i].to;
     46             if(vis[v] || !(i&1))
     47                 continue;
     48             RDFS(v,k);
     49         }
     50     }
     51     void scc()
     52     {
     53         vs.clear();
     54         memF(vis,false,n);
     55         for(int i=1;i <= n;++i)
     56             if(!vis[i])
     57                 DFS(i);
     58 
     59         memF(vis,false,n);
     60         int k=0;
     61         for(int i=vs.size()-1;i >= 0;--i)
     62             if(!vis[vs[i]])
     63                 RDFS(vs[i],++k);
     64     }
     65 }_scc;
     66 vector<int >vs[maxn];
     67 void Solve()
     68 {
     69     for(int i=1;i <= n;++i)///传递闭包
     70         for(int j=1;j <= n;++j)
     71             if(_bit[j][i])
     72                 _bit[j] |= _bit[i];
     73     for(int i=1;i <= n;++i)///构图
     74         for(int j=1;j <= n;++j)
     75             if(_bit[i][j])
     76             {
     77                 addEdge(i,j);
     78                 addEdge(j,i);
     79             }
     80     _scc.scc();
     81     for(int i=1;i <= n;++i)
     82         vs[i].clear();
     83     for(int i=1;i <= n;++i)
     84         vs[col[i]].push_back(i);
     85 
     86     for(int i=1;i <= n;++i)
     87     {
     88         bool flag=false;
     89         for(int j=0;j < vs[i].size();++j)
     90         {
     91             if(!flag)
     92             {
     93                 cout<<g[vs[i][j]];
     94                 flag=true;
     95             }
     96             else
     97                 cout<<", "<<g[vs[i][j]];
     98         }
     99         if(flag)
    100             printf("
    ");
    101     }
    102 }
    103 void Init()
    104 {
    105     num=0;
    106     memF(head,-1,n);
    107     f.clear();
    108     g.clear();
    109     for(int i=0;i <= n;++i)
    110         _bit[i].reset();
    111 }
    112 int main()
    113 {
    114 //    freopen("C:\Users\hyacinthLJP\Desktop\in&&out\contest","r",stdin);
    115     bool flag=false;
    116     int kase=0;
    117     while(~scanf("%d%d",&n,&m) && n+m)
    118     {
    119         Init();
    120         int k=0;
    121         for(int i=1;i <= m;++i)
    122         {
    123             string s1,s2;
    124             cin>>s1>>s2;
    125             if(!f.count(s1))
    126             {
    127                 f[s1]=++k;
    128                 g[k]=s1;
    129             }
    130             if(!f.count(s2))
    131             {
    132                 f[s2]=++k;
    133                 g[k]=s2;
    134             }
    135             _bit[f[s1]].set(f[s2]);
    136         }
    137         if(flag)
    138             printf("
    ");
    139         flag=true;
    140         printf("Calling circles for data set %d:
    ",++kase);
    141         Solve();
    142     }
    143     return 0;
    144 }
    View Code
  • 相关阅读:
    LaTeX技巧22:LaTeX文档中的参考文献初级
    latex 三个不同的图放在一行且每个图都有注释
    CTeX学习心得总结
    latex不能识别eps图片
    山东大学《运筹学》课程课件
    高级算法设计讲义 Lecture Notes for Advanced Algorithm Design
    《计算复杂性》课件
    全球知名大学课件下载地址汇总
    用LaTeX写线性规划
    有感北大校长王恩哥的十句话
  • 原文地址:https://www.cnblogs.com/violet-acmer/p/10947473.html
Copyright © 2020-2023  润新知