zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    JS 利用数组拼接html字符串
    IE浏览器下读取客户端上传的文件大小
    PrintWriter out = response.getWriter() 输出中文乱码问题
    非常有用的Java程序片段
    sql之left join、right join、inner join的区别
    JAVA 数组常用技巧
    java 图片文件格式转换(多页tif转jpg 、jpg转tif)
    SQL Server 字段状态判断语句
    sql server 2008中id如何设为自增
    java基于xml配置的通用excel单表数据导入组件(五、Action处理类)
  • 原文地址:https://www.cnblogs.com/JinxiSui/p/9740536.html
Copyright © 2011-2022 走看看