题解 | #Calling Circles#

Calling Circles

https://ac.nowcoder.com/acm/problem/114100

题目大意:
如果两个人互相打电话(直接或者间接),则说他们在同一个电话圈里。例如,a打给b,b打给c,c打给d,d打给a,则这四个人在同一个圈里;如果e打给f但f不打给e,则不能推出e和f在同一个电话圈。输入n(n<=25)个人的m次电话,找出所有的电话圈。人名只包含字母,不超过25个字符,且不重复。
思路:
(传递闭包)
如果一个节点i与j相连,j与k相连,那么i与k相连
就是计算两点是否相互连通
求传递闭包就是把所有这样的点都弄出来
可以用floyd去搞
代码:

#include <bits/stdc++.h>

using namespace std;
map<string,int>indice;
vector<string>name;
int getid(string s){
     if(!indice.count(s))indice[s]=name.size(),name.push_back(s);
     return indice[s];
}
int main()
{
    int n,m;
    int t=0;
    while(cin>>n>>m){
            if(n==0&&m==0)break;
            if(t>0)cout<<endl;
            int e[30][30]={0},vis[30]={0};
        indice.clear(),name.clear();
        for(int i=0;i<m;i++){
            string a,b;
            cin>>a>>b;
            e[getid(a)][getid(b)]=1;
        }
        for(int k=0;k<n;k++){
            for(int i=0;i<n;i++){
                for(int j=0;j<n;j++)
                    e[i][j]=e[i][j]||(e[i][k]&&e[k][j]);
            }
        }
        cout<<"Calling circles for data set "<<++t<<":"<<endl;
        for(int i=0;i<n;i++){
            if(!vis[i]){
                cout<<name[i];
                vis[i]=1;
                for(int j=0;j<n;j++){
                    if(!vis[j]&&e[i][j]&&e[j][i]){
                            vis[j]=1;
                            cout<<", "<<name[j];
                    }
                }
                cout<<endl;
            }
        }
    }

    return 0;
}
全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务