zoukankan      html  css  js  c++  java
  • UVa

    题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=20840

    #include <iostream>
    #include <string>
    #include <cstring>
    #include <map>
    #include <vector>
    
    using namespace std;
    /***************************************************************************************************************
            题意:A打给B,B打给A,那么AB就构成了一个电话圈。如果A->B,B->C,C->A,那么这也构成了电话圈,
                值得一提的是,如果这种情况下,C->D,D->C,那么D也算是在电话圈内。输出所有的电话圈中的人。
            思路:
            1,学习了 floyd 的 TC ,可以判断两个点是否在一个圈内(利用floyd求出有向图的传递闭包)
                a,初始化相关的两个结点  d[i][j] = 1;
                b,d[i][j] = min (d[i][j],d[i][k] + d[k][j]) 改成 d[i][j] = d[i][j] || (d[i][k] && d[k][j])
                c,判断依据: d[i][j] == d[j][i] == 1
            2,根据传递闭包关系构造新图,输出连通分量中的所有结点
    
            核心:Floyd - TC
    **************************************************************************************************************/
    int dist[30][30];       //标志两个人是否在同一个圈
    int visit[30];
    
    map<string, int> IDcache;       // 姓名 -> 编号
    string name[30];                // 编号 -> 姓名
    int num;
    vector <string> ans[30];
    
    //vector<string> name;              这里本来想这么存名字和最后输出的电话圈的,但是push_back老是用不对
    //vector<vector<string> > ans;      于是改成上面的,string name[]存名字,vector<string> 存电话圈的人
    
    int ID(string s){
        if(IDcache.count(s))    return IDcache[s];
        name[++num] = s;
        return IDcache[s] = num;
    }
    
    int main()
    {
        int n,m;
        int cnt = 0;
        while(cin>>n>>m && n && m){
            num = 0;                                         //一定要初始化
            IDcache.clear();                                 //一定要初始化
            for(int i = 0;i <= n;i ++)  ans[i].clear();      //一定要初始化
    
            string s1,s2;
            memset(dist,0,sizeof(dist));
            for(int i = 1;i <= m;i ++){
                cin>>s1>>s2;
                int id1 = ID(s1),id2 = ID(s2);
                dist[id1][id2] = 1;     //相关即为1
            }
    
            for(int k = 1;k <= n;k ++)
                for(int i = 1;i <= n;i ++)
                    for(int j = 1;j <= n;j ++)
                        dist[i][j] = dist[i][j] || (dist[i][k] && dist[k][j]);      //Floyd的传递闭包(TC)
    
            memset(visit,0,sizeof(visit));
            int len = 0;
            for(int i = 1;i <= n;i ++){
                if(!visit[i]){
                    visit[i] = 1;
                    for(int j = 1;j <= n;j ++){
                        if(visit[j])    continue;
                        if(dist[i][j] && dist[i][j] == dist[j][i]){
                            ans[len].push_back(name[j]);
                            visit[j] = 1;
                        }
                    }
                    ans[len++].push_back(name[i]);
                }
            }
    
            if(cnt)
                cout<<endl;
            cout<<"Calling circles for data set "<<++cnt<<":"<<endl;
            for(int i = 0;i < len;i ++){
                for(int j = 0;j < ans[i].size();j ++){
                    if(j)  cout<<", ";
                    cout<<ans[i][j];
                }
                cout<<endl;
            }
        }
        return 0;
    }
    



  • 相关阅读:
    基于视网膜虹膜识别的内容分级系统
    C# 反射详解一
    C# 委托浅析
    .Net Core中使用Dapper构建泛型仓储
    C# 泛型详解
    非对称可逆加密RSA
    对称可逆加密Des
    .NET Core 3.0 中间件 Middleware
    .NET Core3.0 日志 logging
    .Net Core3.0依赖注入DI
  • 原文地址:https://www.cnblogs.com/Jstyle-continue/p/6351957.html
Copyright © 2011-2022 走看看