• UVa247


    题意

    电话圈, 每行输出在一个圈内的人名

    思路

    有向图的传递闭包
    该有向图中, 并不需要关心路径长度, 只需要关心两点之间是否有通路, 则可以用”1”和”0”表示”连通”和”不连通”. 这样只需要将floyed算法中的语句改为 d[i][j] = d[i][j]||(d[i][k]&&d[k][j]) 即可求得传递闭包

    AC代码

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <string>
    #include <map>
    #include <set>
    #include <vector>
    
    using namespace std;
    const int INF = 0x3f3f3f3f;
    int n, m;
    map<int, string> ID;
    set<string> names;
    const int maxn = 30;
    int g[maxn][maxn];
    int f[maxn];
    vector<string> vec[maxn];
    
    void init()
    {
        if(!names.empty())  names.clear();
        if(!ID.empty())     ID.clear();
        for( int i = 0; i <= n; i++ )
            vec[i].clear();
        memset(g, 0, sizeof g);
        for(int i = 1; i <= n; i++)
            f[i] = i;
    }
    
    int find_(int a)
    {
        if( f[a] != a ) f[a] = find_(f[a]);
        return f[a];
    }
    
    void union_(int a, int b)
    {
        int aa = find_(a), bb = find_(b);
        if(aa!=bb)
        {
            f[bb] = aa;
        }
        return;
    }
    
    void floyed(){   // floyed 求传递闭包
        for(int k = 1; k <= n; k++)
            for(int i = 1; i <= n; i++)
                for(int j = 1; j <= n; j++)
                    g[i][j] = g[i][j] || (g[i][k] && g[k][j]);
    }
    
    int findid(string a){
        map<int, string>::iterator it = ID.begin();
        for(;it!=ID.end();it++){
            if( it->second == a )
                return it->first;
        }
    }
    
    int main()
    {
        string stra, strb;
        int cnt;
        int num = 0;
        while( cin >> n >> m && n && m ){
            cnt = 0;
            init();
            for(int i = 0; i < m; i++){
                cin >> stra >> strb;
                if(!names.count(stra)){ ID[++cnt] = stra; names.insert(stra); }
                if(!names.count(strb)){ ID[++cnt] = strb; names.insert(strb); }
                g[findid(stra)][findid(strb)] = 1;
            }
            floyed();
            printf("Calling circles for data set %d:
    ", ++num);
            for(int i = 1 ; i <= n; i++ ){
                for(int j = i+1; j <= n; j++){
                    if( g[i][j] == 1 && g[j][i] == 1 ){
                        union_(i, j);
                    }
                }
            }
            for(int i = 1; i <= n; i++)
            {
                vec[f[i]].push_back(ID[i]);
            }
            for(int i = 1; i <= n; i++){
                if( vec[i].size() == 0 ) continue;
                for(int j = 0; j < (int)vec[i].size(); j++){
                    if( j != 0 ) cout << ", ";
                    cout << vec[i][j];
                }
                cout << "
    ";
            }
        }
        return 0;
    }
  • 相关阅读:
    PHP的strtotime()函数2038年bug问题
    [转]MySQL常用字符串函数
    [转]MySQL日期与时间戳常用函数
    微信公众号开发的一点自我小结,怕自己过后忘了,总结于此。
    [转]去掉IOS下的input 和textarea的内阴影
    [转]Javascript removeChild()删除节点及删除子节点的方法(同样适用于jq)
    能够还原jQuery1.8的toggle的功能的插件
    xp sp3安装.Net 4.0提示严重错误,0x80070643,解决办法2017版
    thinkphp5访问sql2000数据库
    微信网页授权,错误40163,ios正确,安卓错误?
  • 原文地址:https://www.cnblogs.com/JinxiSui/p/9740536.html
Copyright © 2020-2023  润新知