题意:如果两个人互通电话,那么他们就在一个电话圈里,现在给定 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. cocos2dx Scene,Layer,Sprite的理解

    layer,scene,sprite的默认锚点都是0.5,0.5 三者都继承自Node节点,暂时没看出有什么区别,或者下面的话是对的吧. 在cocos2d-x中,一个应用可以有多个scene,但任何时 ...

  2. ubuntu 16.04安装HUSTOJ过程

    一.背景介绍: 因为工作需要,想在学校搭建一个OJ平台用于程序测试与评价.于是需要搭建oJ,由于之前都是在云端服务器搭建系统,没有在实际服务器平台搭建过,所以遇到不少坑,都靠自己来填补.故而写下此教程 ...

  3. 归并排序算法-python实现

    #-*- coding: UTF-8 -*- import numpy as np def Merge(a, f, m, l): i = f j = m + 1 tmp = [] while i &l ...

  4. bootstrap全局css样式

    以下从官网抄来的,感觉还是很实用的,运用得好,灵活运用,非常方便快捷,能大大提高开发效率,也为调整不同尺寸的屏幕节省了时间. hidden-xs @media (max-width: 767px){ ...

  5. 2018-2019-1 20165226《信息安全系统设计基础》 pwd命令的实现

    2018-2019-1 20165226<信息安全系统设计基础> pwd命令的实现 一.学习pwd 查看pwd 得知一个嫩过去文件路径的函数--getcwd i节点值 通过ls -i -a ...

  6. Bootstrap-CL:警告

    ylbtech-Bootstrap-CL:警告 1.返回顶部 1. Bootstrap 警告(Alerts) 本章将讲解警告(Alerts)以及 Bootstrap 所提供的用于警告的 class.警 ...

  7. Solr进行Distinct 获取Count

    今天碰到一个问题,数据之前入solr的时候并没有计算条数,现在需要计算出某几个表中去重后的总数. 由于solr的ISearch并没有相关的Distinct功能.想到一个解决方案是用Solr的Facet ...

  8. 测试Linux端口的连通性的四种方法

    Linux系统有时候需要测试某个端口的连通性,用户可以参考如下方法来测试.   方法一.telnet法 telnet为用户提供了在本地计算机上完成远程主机工作的能力,因此可以通过telnet来测试端口 ...

  9. uwsgi的python2+3多版本共存实操使用virtualenv

    1首先,机器需要有python2和python3的可执行环境.确保pip和pip3命令可用.原理就是在哪个环境下安装uwsgi.uwsgi启动的时候,就用的哪个python版本 2安装virtuale ...

  10. Javascript 日期 加减

    //create the date var myDate = new Date(); //add a day to the date myDate.setDate(myDate.getDate() + ...