UVa 247 Calling Circles (DFS+Floyd)
题意:如果两个人互通电话,那么他们就在一个电话圈里,现在给定 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)的更多相关文章
- UVa 247 - Calling Circles(Floyd求有向图的传递闭包)
链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...
- UVA 247"Calling Circles"(floyd求传递闭包+SCC)
传送门 题意: 如果两个人相互打电话(直接或间接),则说他们在同一个电话圈里. (a,b) 表示 a 打给 b: 例如,(a,b),(b,c),(c,d),(d,a),则这四个人在同一个电话圈里: 输 ...
- UVA - 247 Calling Circles(Floyd求传递闭包)
题目: 思路: 利用Floyd求传递闭包(mp[i][j] = mp[i][j]||(mp[i][k]&&mp[k][j]);),当mp[i][j]=1&&mp[j][ ...
- UVA 247 - Calling Circles (Floyd)
互相可以打电话是一个传递关系,所以Floyd求传递封包,dfs找一个尽量大的圈. #include<bits/stdc++.h> using namespace std; ; map< ...
- UVA 247 Calling Circles —— (强连通分量模板题)
第一个强连通分量的题. 题意:有一堆人,a给b打电话表示a有一条向b的边,一个强连通分量代表一个电话圈,把每个电话圈里的人在一行内输出出来. 直接上模板即可,但是要注意把string用map映射一下的 ...
- 【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的复杂度都没有 ...
- UVA - 247 Calling Circles Floyd判圈
思路:利用的Floyd判圈,如果i能到j,j也能到i说明i和j在同一个圈里.每个人的名字可用map编号.最后DFS打印答案即可. AC代码 #include <cstdio> #inclu ...
- UVa 247 Calling Circles【传递闭包】
题意:给出n个人的m次电话,问最后构成多少个环,找出所有的环 自己想的是:用map来储存人名,每个人名映射成一个数字编号,再用并查集,求出有多少块连通块,输出 可是map不熟,写不出来,而且用并查集输 ...
- UVa 1343 旋转游戏(dfs+IDA*)
https://vjudge.net/problem/UVA-1343 题意:如图所示,一共有8个1,8个2和8个3,如何以最少的移动来使得中间8个格子都为同一个数. 思路:状态空间搜索问题. 用ID ...
随机推荐
- curl查询公网出口IP
liuzhizhi@lzz-rmbp|logs # curl ipinfo.io { "ip": "114.110.1.38", "hostname& ...
- 【白银组】codevs_1011 数的计算
简单而言,就是递归的运用,注意使用全局变量统计cnt,并且注意递归的结束,中间生成的值无需进行输出. http://codevs.cn/problem/1011/ #include<iostre ...
- SQL2008如何清空压缩数据库日志
SQL2008如何清空压缩数据库日志 编写人:左丘文 2015-4-10 近期在给一系统初始化资料时,不断的导入导出,因此一不小心,就将数据的SQL(sql2008R2)的是日志档弄得比数据库还大,给 ...
- Python 中函数和方法
函数与方法 class Foo(object): def __init__(self): self.name = 'lcg' def func(self): print(self.name) obj ...
- Django将.csv文件(excel文件)显示到网页上
今天,我成功将项目要导入的测试数据导入并呈现了,虽然还不是很完美,但我之后仍会继续改进. 1.首先在主页面上加一个超链接按钮: 其它的不需要管,其它是我的另一个项目,没什么大用的 2.之后配置URL: ...
- MikroTik-ROS-无线设备传输距离
近期在MikroTik官网论坛给出了官方无线成品设备的最大传输距离. 以下设备列表基于理想的环境条件,包括干扰,天气,校准精度等因素,表给出了基于802.11ac或802.11n在获取最大传输带宽的情 ...
- 自动手动随便你 Win7驱动程序安装自己设
Win7系统是非常智能方便的操作系统,可以自动安装硬件驱动程序,为用户提供了很多方便.但是并不是所有的驱动程序和硬件都能完美兼容,如果不合适就需要卸载了重新安装:还有一些朋友就习惯自己安装驱动,那么, ...
- 微信小程序从子页面退回父页面时的数据传递 wx.navigateBack()
我们知道,在微信小程序中,从一个页面转到另一个页面,一般情况下可以通过navigate或redirect时候的url来携带参数,然后在目标页面的onLoad函数参数中获取这些url参数.例如: // ...
- pythonNET day05
孤儿进程 父进程先于子进程退出,此时子进程就会成为孤儿进程. 孤儿进程会被系统指定的进程收养,即系统进程会成为该孤儿进程新的父进程.孤儿进程退出时该父进程会处理退出状态 僵尸进程 子进程先于父进程退出 ...
- 转 linux 下装 usb driver
http://www.george-smart.co.uk/wiki/Xilinx_JTAG_Linux