题意:如果两个人互通电话,那么他们就在一个电话圈里,现在给定 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. Linux中epoll+线程池实现高并发

    服务器并发模型通常可分为单线程和多线程模型,这里的线程通常是指“I/O线程”,即负责I/O操作,协调分配任务的“管理线程”,而实际的请求和任务通常交由所谓“工作者线程”处理.通常多线程模型下,每个线程 ...

  2. [CLPR] 卷积神经网络的结构

    本文翻译自: http://www.codeproject.com/Articles/16650/Neural-Network-for-Recognition-of-Handwritten-Digi ...

  3. sublime text 3 配置优化

    1.在用Sublime里编写代码时,需要把TAB键转换成四个空格. 菜单栏里点击:首选项-> 设置-用户(Preferences-> Setting-User)在弹出来的文本里,添加如下两 ...

  4. laravel 整合 swoole ,并简单 ab 测试对比性能以及在 PHPstorm 中利用debug调试配置swoole服务中的PHP代码

    安装PHP 的 swoole 扩展 及 安装 laravel,就不描述了 整合 laravel 和 swoole 用了这个轮子,侵入性很小,一行代码搞定,推荐一下,今天刚用,不能预测未来是否会遇见坑 ...

  5. iis 更改asp.net 版本设置

    参考来源: https://github.com/neo2018/ZYFC/blob/2e20009097c1e837a6e667a3dffd4224e28f4411/MderFc/Classes/I ...

  6. (转)ASP连接sql server实例解析

    本文转载自:http://blog.csdn.net/xys_777/article/details/5696276 1.首先确定自己的iis没有问题 2.其次确定自己sqlserver没有问题 然后 ...

  7. [html][javascript]动态增删页面元素

    <script type="text/javascript"> function append(event){ var myhref = document.create ...

  8. Appium使用ID进行定位

      1 使用uiautomatorviewer地获取元素ID 路径:sdk\tools\uiautomatorviewer.bat 2 脚本中增加点击事件 driver.find_element_by ...

  9. Redux 处理异步 Action

    redux-promise-utils What redux-promise-utils 是一个基于 redux-thunk 和 redux-actions 的工具,符合 FSA 规范,方便开发者处理 ...

  10. OpenCL 使用函数 clCreateProgramWithBinary 来创建程序

    ▶ 函数 clCreateProgramWithSource 接收 OpenCL 代码(设备无关)来创建程序,而函数 clCreateProgramWithBinary 接收已经经过函数 clBuil ...