题意:如果两个人互通电话,那么他们就在一个电话圈里,现在给定 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. asp.net(C#)链接Oracle连接字符串

    在NET环境中链接Oracle数据库有两种组建链接方式: 1)使用OleDB组件是通过Oracle OleDB驱动程序(OraOLEDB.dll)连接和访问Oracle数据库2)使用System.Da ...

  2. bzoj 1002 [FJOI2007]轮状病毒——打表找规律

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1002 看 Zinn 的博客:https://www.cnblogs.com/Zinn/p/9 ...

  3. haproxy 安装与配置

    一. Haproxy 介绍 HAProxy提供高可用性.负载均衡以及基于TCP和HTTP应用的代理,支持虚拟主机,它是免费.快速并且可靠的一种解决方案.根据官方数据,其最高极限支持10G的并发.HAP ...

  4. WinForm 每用户只允许创建一个实例

    string mutexName = System.Environment.UserName + "nono"; bool runone; System.Threading.Mut ...

  5. erlang的一些系统限制修改

    atom个数限制 +t xxx 进程数限制 +P xxxx ets表个数限制 +e xxx ports个数限制 +Q xxxx 查看限制 string:tokens(binary_to_list(er ...

  6. Waiting for device dev/disk/by-id/ata-...-part2 to appear

    问题: 平台:Oralce VM Virtualbox的虚拟机Opensuse11.4 导出该机器的OVA文件后,把该OVA文件导入虚拟机,开机启动时报如下错误: Trying manual resu ...

  7. SpringBoot2.0实现静态资源版本控制

    写在最前面 犹记毕业第一年时,公司每次发布完成后,都会在一个群里通知[版本更新,各部门清理缓存,有问题及时反馈]之类的话.归根结底就是资源缓存的问题,浏览器会将请求到的静态资源,如JS.CSS等文件缓 ...

  8. Selenium2+python自动化62-jenkins持续集成环境搭建

    前言 selenium脚本写完之后,一般是集成到jenkins环境了,方便一键执行. 一.环境准备 小编环境: 1.win10 64位 2.JDK 1.8.0_66 3.tomcat 9.0.0.M4 ...

  9. 超文本传输协议http详解

    HTTP是一个属于应用层的面向对象的协议,由于其简捷.快速的方式,适用于分布式超媒体信息系统.它于1990年提出,经过几年的使用与发展,得到不断地完善和扩展.目前在WWW中使用的是HTTP/1.0的第 ...

  10. urllib2 Handler处理器和自定义opener(六)

    Handler处理器 和 自定义Opener opener是 urllib2.OpenerDirector 的实例,我们之前一直都在使用的urlopen,它是一个特殊的opener(也就是模块帮我们构 ...