传送门

题意:

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

  (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. Leetcode3.Longest Substring Without Repeating Characters无重复字符的最长字串

    给定一个字符串,找出不含有重复字符的最长子串的长度. 示例 1: 输入: "abcabcbb" 输出: 3 解释: 无重复字符的最长子串是 "abc",其长度为 ...

  2. less知识点总结(二)

    变量:以@开头,由于变量只能定义一次,其本质就是“常量”. @nice-blue: #5B83AD; @light-blue: @nice-blue + #; #header { color: @li ...

  3. RapidMiner Studio 入门

    http://docs.rapidminer.com/studio/getting-started/ RapidMiner Studio 入门 FEIFEI MA 2015-12-07RAPIDMIN ...

  4. @topcoder - SRM766R1 D1L3@ ShortestMissingSubsequences

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 给定一个大小为 G 的字符集,并给定一个长度为 N 的字符串 A ...

  5. Android实战:手把手实现“捧腹网”APP(二)-----捧腹APP原型设计、实现框架选取

    Android实战:手把手实现"捧腹网"APP(一)-–捧腹网网页分析.数据获取 Android实战:手把手实现"捧腹网"APP(二)-–捧腹APP原型设计.实 ...

  6. nodeJs学习-11 multer中间件,解析post文件,上传文件

    const express=require('express'); const bodyParser=require('body-parser'); const multer=require('mul ...

  7. MyEclipse代码提示功能和自动提示功能

    1.菜单window->Preferences->Java->Editor->Content Assist->Enable auto activation 选项要打上勾 ...

  8. Docker初步了解 2016-10-30 20:46 279人阅读 评论(31) 收藏

    什么是docker? Docker是一个开源的引擎,可以轻松的为任何应用创建一个轻量级的.可移植的.自给自足的容器. Docker本质上是一种软件,让用户创建镜像(很像虚拟机的模板),并且随后在容器里 ...

  9. C/S和B/S交互 2016-03-19 11:27 1275人阅读 评论(30) 收藏

    最近一直在做C/S的项目,每天都超忙,抽个时间写篇博客,之前一直做C/S项目就是各种窗体,各种控件,拖来拖去,然后点进去写方法,做BS的时候呢,因为一直使用的是mvc,所以就是经常手写代码,或者拖引用 ...

  10. SQL if语句简要

    if语句 可以作为表达式用 可以在存储过程中作为流程控制语句用 表达式 IF(条件,条件true,条件false) 示例 sex字段m,f 互换 update salary set sex = if( ...