题意:如果两个人互通电话,那么他们就在一个电话圈里,现在给定 n 个人,并且给定 m 个通话记录,让你输出所有的电话圈。

析:刚开始没想到是Floyd算法,后来才知道是这个算法,利用这个算法进行连通性的判定,当且仅当d[i][j] = d[j][i] = 1时,他们是在一个圈里。

然后用Floyd算法,把所有的关系都找到,最后再用DFS输出即可。通过这个题发现阶段不一样,那么写出来的东西也就不一样,这是第二次做这个题了,

第一次没用DFS,用的是set和map,来输出和记录。

代码如下:

第一次的

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <map>
#include <string>
#include <vector>
#include <set> using namespace std;
const int INF = 0x3f3f3f3f;
const int maxn = 30 + 5;
map<string, int> mp;
int d[30][30];
vector<int> G[maxn]; int main(){
// freopen("int.txt", "r", stdin);
int n, m, cases = 0;
while(scanf("%d %d", &n, &m)){
if(!m && !n) break; for(int i = 0; i < maxn; ++i)
G[i].clear();
mp.clear();
string s1, s2;
memset(d, 0, sizeof(d));
int indx = 1;
for(int i = 0; i < m; ++i){
cin >> s1 >> s2;
if(!mp.count(s1)) mp[s1] = indx++;//获得编号
if(!mp.count(s2)) mp[s2] = indx++;
d[mp[s1]][mp[s2]] = 1;
} for(int k = 1; k <= n; ++k)//Floyd算法判断连通性
for(int i = 1; i <= n; ++i)
for(int j = 1; j <= n; ++j)
d[i][j] = d[i][j] || (d[i][k] && d[k][j]); set<int> sets;
for(int i = 1; i <= n; ++i){
if(sets.count(i)) continue;//判断是不是已经放过了
G[i].push_back(i);
sets.insert(i);
for(int j = 1; j <= n; ++j)
if(i != j && d[i][j] && d[j][i]){ G[i].push_back(j); sets.insert(j); }
} if(cases) printf("\n");
printf("Calling circles for data set %d:\n", ++cases);
for(int i = 1; i <= n; ++i){
if(!G[i].size()) continue;
for(int j = 0; j < G[i].size(); ++j){
if(j) printf(", ");
for(map<string, int> :: iterator it = mp.begin(); it != mp.end(); ++it)//遍历map
if(it->second == G[i][j]){ cout << it->first; break; }
}
printf("\n");
}
}
return 0;
}

我都发现写的好差劲啊。。。。。

这是第二次的,还可以吧

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <map>
#include <string>
#include <cstring>
#include <vector> using namespace std;
const int maxn = 25 + 5;
int cnt, n;
int d[maxn][maxn], vis[maxn]; vector<string> name; int getid(const string &s){//记录编号
for(int i = 0; i < name.size(); ++i)
if(name[i] == s) return i;
name.push_back(s);
return name.size()-1;
} void dfs(int u){//递归输出
vis[u] = 1;
for(int i = 0; i < n; ++i)
if(!vis[i] && d[u][i] && d[i][u]){
cout << ", " << name[i];
dfs(i);
}
return ;
} int main(){
// freopen("in.txt", "r", stdin);
int m, kase = 0;
while(scanf("%d %d", &n, &m) == 2 && n){
name.clear();
string s1, s2;
memset(d, 0, sizeof(d));
memset(vis, 0, sizeof(vis));
while(m--){
cin >> s1 >> s2;
int u = getid(s1);
int v = getid(s2);
d[u][v] = 1;
} for(int k = 0; k < n; ++k)//Floyd算法判断连通性
for(int i = 0; i < n; ++i)
for(int j = 0; j < n; ++j)
d[i][j] |= d[i][k] && d[k][j]; if(kase) printf("\n");
printf("Calling circles for data set %d:\n", ++kase);
for(int i = 0; i < n; ++i) if(!vis[i]){
cout << name[i];
dfs(i);
cout << endl;
}
}
return 0;
}

UVa 247 Calling Circles (DFS+Floyd)的更多相关文章

  1. UVa 247 - Calling Circles(Floyd求有向图的传递闭包)

    链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...

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

    传送门 题意: 如果两个人相互打电话(直接或间接),则说他们在同一个电话圈里. (a,b) 表示 a 打给 b: 例如,(a,b),(b,c),(c,d),(d,a),则这四个人在同一个电话圈里: 输 ...

  3. UVA - 247 Calling Circles(Floyd求传递闭包)

    题目: 思路: 利用Floyd求传递闭包(mp[i][j] = mp[i][j]||(mp[i][k]&&mp[k][j]);),当mp[i][j]=1&&mp[j][ ...

  4. UVA 247 - Calling Circles (Floyd)

    互相可以打电话是一个传递关系,所以Floyd求传递封包,dfs找一个尽量大的圈. #include<bits/stdc++.h> using namespace std; ; map< ...

  5. UVA 247 Calling Circles —— (强连通分量模板题)

    第一个强连通分量的题. 题意:有一堆人,a给b打电话表示a有一条向b的边,一个强连通分量代表一个电话圈,把每个电话圈里的人在一行内输出出来. 直接上模板即可,但是要注意把string用map映射一下的 ...

  6. 【uva 247】Calling Circles(图论--Floyd 传递闭包+并查集 连通分量)

    题意:有N个人互相打了M次电话,请找出所有电话圈(Eg.a→b,b→c,c→d,d→a 就算一个电话圈)并输出.(N≤25,L≤25,注意输出格式) 解法:由于N比较小所有n^2或n^3的复杂度都没有 ...

  7. UVA - 247 Calling Circles Floyd判圈

    思路:利用的Floyd判圈,如果i能到j,j也能到i说明i和j在同一个圈里.每个人的名字可用map编号.最后DFS打印答案即可. AC代码 #include <cstdio> #inclu ...

  8. UVa 247 Calling Circles【传递闭包】

    题意:给出n个人的m次电话,问最后构成多少个环,找出所有的环 自己想的是:用map来储存人名,每个人名映射成一个数字编号,再用并查集,求出有多少块连通块,输出 可是map不熟,写不出来,而且用并查集输 ...

  9. UVa 1343 旋转游戏(dfs+IDA*)

    https://vjudge.net/problem/UVA-1343 题意:如图所示,一共有8个1,8个2和8个3,如何以最少的移动来使得中间8个格子都为同一个数. 思路:状态空间搜索问题. 用ID ...

随机推荐

  1. oracle 脚本创建数据库的相关文章,教程,源码

    学步园推荐专题: 关于oracle 脚本创建数据库的相关文章 文章标题 文章链接 文章简介 oracle命令行创建数据库的示例脚本 http://www.xuebuyuan.com/964527.ht ...

  2. JSON用法之将PHP数组转JS数组,JS如何接收PHP数组

    先看php文件,当我们获取到$arr这个数组后 foreach ($arr as $value) { $json .= json_encode($value) . ','; } echo '[' . ...

  3. ASI接口

    Asynchronous Serial Interface ,异步串行接口,用于传送码流的一个标准DVB接口. 在目前的DVB-C系统设备的传输接口有两种MPEG2视频码流传输接口标准:异步串行接口A ...

  4. springMVC等小知识点记录。。。持续更新

    1.springMVC 项目根路径访问页面配置 <!-- 表示当访问主页时自动转发到index控制器 --> <mvc:view-controller path="/&qu ...

  5. ElasticSearch之CURL操作

    CURL的操作    curl是利用URL语法在命令行方式下工作的开源文件传输工具,使用curl可以简单实现常见的get/post请求.简单的认为是可以在命令行下面访问url的一个工具.在centos ...

  6. mysql-10临时表、复制表

    1.创建临时表 mysql临时表在我们需要保存一些临时数据时非常有用. 临时表只在当前连接可见,当关闭连接时,mysql会自动删除表并释放所有空间. 如果使用客户端创建临时表,只有在管不客户端程序时才 ...

  7. Java 序列化接口Serializable详解

    一个对象序列化的接口,一个类只有实现了Serializable搜索接口,它的对象才是可序列化的.因此如果要序列化某些类的对象,这些类就必须实现Serializable接口.而实际上,Serializa ...

  8. 记一次在 Ubutun16.04 LTS 系统的 python-environment 安装 MySQL-python 的心(苦)路(笑)旅程

    背景 之前项目需要准备线啦, 那么好了~~ 数据库也从测试时使用的 SQLITE 升级到了 MYSQL (高大上的免费且开源的关系型数据库,要不要了解一下!) 巧合的是,同事使用的是MySQL-pyt ...

  9. Maven的依赖机制介绍

    以下内容引用自https://ayayui.gitbooks.io/tutorialspoint-maven/content/book/maven_manage_dependencies.html: ...

  10. Entity Framework的优势和缺点

    优点:简单说就是Entity Framework省事,做业务系统,管理系统会减少很多代码,程序员可以更关注业务实现本身. 缺点:当处理大数据量和高并发时,由于Entity Framework是自动化程 ...