传送门

题意:

  如果两个人相互打电话(直接或间接),则说他们在同一个电话圈里。

  (a,b) 表示 a 打给 b;

  例如,(a,b),(b,c),(c,d),(d,a),则这四个人在同一个电话圈里;

  输入 n(n≤25) 个人的 m 次电话,找出所有的电话圈,输出每个电话圈里的人名(无序)。

题解:

  首先用floyd求出传递闭包,构造新图;

  然后在新图上跑一遍SCC求解;

AC代码:

 #include<bits/stdc++.h>
using namespace std;
#define memF(a,b,n) for(int i=0;i <= n;a[i]=b,++i);
const int maxn=; int n,m;
int num;
int head[maxn];
struct Edge
{
int to;
int next;
}G[maxn*maxn*];
void addEdge(int u,int v)
{
G[num]={v,head[u]};
head[u]=num++;
}
map<string ,int >f;
map<int ,string >g;
bitset<maxn>_bit[maxn];
int col[maxn];
struct SCC
{
vector<int >vs;
bool vis[maxn];
void DFS(int u)
{
vis[u]=true;
for(int i=head[u];~i;i=G[i].next)
{
int v=G[i].to;
if(vis[v] || (i&))
continue;
DFS(v);
}
vs.push_back(u);
}
void RDFS(int u,int k)
{
vis[u]=true;
col[u]=k;
for(int i=head[u];~i;i=G[i].next)
{
int v=G[i].to;
if(vis[v] || !(i&))
continue;
RDFS(v,k);
}
}
void scc()
{
vs.clear();
memF(vis,false,n);
for(int i=;i <= n;++i)
if(!vis[i])
DFS(i); memF(vis,false,n);
int k=;
for(int i=vs.size()-;i >= ;--i)
if(!vis[vs[i]])
RDFS(vs[i],++k);
}
}_scc;
vector<int >vs[maxn];
void Solve()
{
for(int i=;i <= n;++i)///传递闭包
for(int j=;j <= n;++j)
if(_bit[j][i])
_bit[j] |= _bit[i];
for(int i=;i <= n;++i)///构图
for(int j=;j <= n;++j)
if(_bit[i][j])
{
addEdge(i,j);
addEdge(j,i);
}
_scc.scc();
for(int i=;i <= n;++i)
vs[i].clear();
for(int i=;i <= n;++i)
vs[col[i]].push_back(i); for(int i=;i <= n;++i)
{
bool flag=false;
for(int j=;j < vs[i].size();++j)
{
if(!flag)
{
cout<<g[vs[i][j]];
flag=true;
}
else
cout<<", "<<g[vs[i][j]];
}
if(flag)
printf("\n");
}
}
void Init()
{
num=;
memF(head,-,n);
f.clear();
g.clear();
for(int i=;i <= n;++i)
_bit[i].reset();
}
int main()
{
// freopen("C:\\Users\\hyacinthLJP\\Desktop\\in&&out\\contest","r",stdin);
bool flag=false;
int kase=;
while(~scanf("%d%d",&n,&m) && n+m)
{
Init();
int k=;
for(int i=;i <= m;++i)
{
string s1,s2;
cin>>s1>>s2;
if(!f.count(s1))
{
f[s1]=++k;
g[k]=s1;
}
if(!f.count(s2))
{
f[s2]=++k;
g[k]=s2;
}
_bit[f[s1]].set(f[s2]);
}
if(flag)
printf("\n");
flag=true;
printf("Calling circles for data set %d:\n",++kase);
Solve();
}
return ;
}

UVA 247"Calling Circles"(floyd求传递闭包+SCC)的更多相关文章

  1. UVA - 247 Calling Circles Floyd判圈

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

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

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

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

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

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

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

  5. UVA 247 - Calling Circles (Floyd)

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

  6. UVa 247 Calling Circles (DFS+Floyd)

    题意:如果两个人互通电话,那么他们就在一个电话圈里,现在给定 n 个人,并且给定 m 个通话记录,让你输出所有的电话圈. 析:刚开始没想到是Floyd算法,后来才知道是这个算法,利用这个算法进行连通性 ...

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

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

  8. 【Calling Circles UVA - 247 】【Floyd + dfs】

    用到的东西 Floyd算法(不考虑路径的长度,只关心两点之间是否有通路,可用于求有向图的传递闭包) STL map中的count用法 利用dfs输出同一个圈内的名字 题意 题目中给出 n 的人的名字, ...

  9. UVA 247 电话圈(Floyd传递闭包+输出连通分量)

    电话圈 紫书P365 [题目链接]电话圈 [题目类型]Floyd传递闭包+输出连通分量 &题解: 原来floyd还可以这么用,再配合连通分量,简直牛逼. 我发现其实求联通分量也不难,就是for ...

随机推荐

  1. 利用IE浏览器查看元素绑定的JS代码

  2. jreble for eclipse配置

    1 下载安装jrebel for eclipse  安装方法不再赘述.常规方式Install via Eclipse Marketplace->earch for JRebel 2 安装之后替换 ...

  3. c# 日期函数

    DateTime dt = DateTime.Now;Label1.Text = dt.ToString();//2005-11-5 13:21:25Label2.Text = dt.ToFileTi ...

  4. Directx教程(28) 简单的光照模型(7)

    原文:Directx教程(28) 简单的光照模型(7)        现实生活中的点光源都是随着距离衰减的,比如一个电灯泡在近处会照的很亮,远处光线就很弱.本节中我们在前面光公式的基础上,再给漫反射和 ...

  5. MaxCompute问答整理之6月

    本文是基于本人对MaxCompute产品的学习进度,再结合开发者社区里面的一些问题,进而整理成文.希望对大家有所帮助,下面咱们正式开始. 1.什么是MaxCompute呢?MaxCompute是由阿里 ...

  6. sed 命令用法

    Sed:对文件进行编辑操作,对象是行.操作后在屏幕输出结果.如果要直接修改则加-i命令-f filename: 执行某文件内的sed命令-n 只显示被修改的那一行 如文件test内容:Letyou a ...

  7. Laravel 登录后清空COOKIE 方法

    需求 在Laravel 登陆立即清空保存的COOKIE数组 实现 # Http/Controllers/Auth/LoginController.php public function redirec ...

  8. Linux使用及命令

    #命令模式下输入:光标移动到第34行第15个字符 <Enter>15l(这是小写的L) ctrl+u删除光标前面的字符 ctrl+j删除光标后面的字符 在Linux下用VIM打开大小几个G ...

  9. zabbix源码编译安装以及添加第一台host监控

    基础准备 硬件需求 数据库需求   软件需求 其他软件需求 安装 安装方式 source code 编译好的二进制包 rpm或者deb 源码编译安装部署zabbix以及附件 前提准备 最小化安装操作系 ...

  10. Java练习 SDUT-3849_分数四则运算

    分数四则运算 Time Limit: 1000 ms Memory Limit: 65536 KiB Problem Description 编写程序,实现两个分数的加减法 Input 输入包含多行数 ...