UVA 247 电话圈 (floyd传递闭包 + dfs输出连通分量)

题意:输出所有的环;

思路:数据比较小,用三层循环的floyd传递闭包(即两条路通为1,不通为0,如果在一个环中,环中的所有点能互相连通),输出路径用dfs,递归还没有出现过的点(vis),输出并递归该点与其他点能互达的点;

 1 #include <cstdio>
 2 #include <vector>
 3 #include <string>
 4 #include <cstring>
 5 #include <iostream>
 6 using namespace std;
 7 #define repu(i,a,b) for(int i=a;i<b;i++)
 8 #define INF 10010
 9 vector<string> str;
10 #define N 30
11 int d[N][N],vis[N];
12
13 int ID(string s)
14 {
15     repu(i,0,str.size())
16     if(str[i] == s)
17         return i;
18     str.push_back(s);
19     return str.size()-1;
20 }
21
22 int n,m;
23 int dfs(int k)
24 {
25     vis[k] = 1;
26     repu(j,0,n)
27     if(!vis[j] && d[j][k] && d[k][j])
28     {
29         cout<<", "<<str[j];
30         dfs(j);
31     }
32 }
33
34 int main()
35 {
36     int kase = 0;
37     while(scanf("%d%d",&n,&m) && n && m)
38     {
39         str.clear();
40         string s,c;
41         if(kase)
42             printf("\n");
43         repu(i,0,n)
44         repu(j,0,n)
45         d[i][j] = (i == j)?1:0;
46
47         repu(i,0,m)
48         {
49             cin>>s>>c;
50             int x = ID(s);
51             int y = ID(c);
52             d[x][y] = 1;
53         }
54         printf("Calling circles for data set %d:\n",++kase);
55         repu(k,0,n)///传递闭包
56         repu(i,0,n)
57         repu(j,0,n)
58         d[i][j] |= (d[i][k] && d[k][j]);
59
60         memset(vis,0,sizeof(vis));///递归输出路径
61         repu(i,0,n)
62         if(!vis[i])
63         {
64             cout<<str[i];
65             dfs(i);
66             printf("\n");
67         }
68     }
69     return 0;
70 }

时间: 2024-11-08 21:24:51

UVA 247 电话圈 (floyd传递闭包 + dfs输出连通分量)的相关文章

UVa 247 电话圈(Floyd传递闭包)

https://vjudge.net/problem/UVA-247 题意: 如果两个人相互打电话,则说他们在同一个电话圈里.例如,a打给b,b打给c,c打给d,d打给a,则这4个人在同一个圈里:如果e打给f但f不打给e,则不能推出e和f在同一个电话圈里,输出所有电话圈. 思路: 通过Floyd求一个传递闭包.最后dfs输出每一个电话圈即可. 传递闭包的求法: 1 for (int k = 0; k < n;k++) 2 for (int i = 0; i < n;i++) 3 for (in

UVa 247 Calling Circles【传递闭包】

题意:给出n个人的m次电话,问最后构成多少个环,找出所有的环 自己想的是:用map来储存人名,每个人名映射成一个数字编号,再用并查集,求出有多少块连通块,输出 可是map不熟,写不出来,而且用并查集输出的时候感觉貌似很麻烦 然后再用的传递闭包,可是判断到d[i][j]==1和d[j][i]==1,该怎么输出路径呢 于是看了lrj的代码= = 用的是一个ID(string s)函数来给名字编号,和第五章的集合栈计算机那题的办法一样 然后用dfs输出路径= =(这个要好好--好好--好好学) 最后还

【UVA】247 - Calling Circles(floyd判断包闭,dfs输出)

最近状态不佳,总是爱犯低级错误,比较水的题,没什么需要讲得,要说的可能是floyd判断包闭吧 void Floyd() { for(int k=1; k<=n; k++) for(int i=1; i<=n; i++) if(map[i][k]) for(int j=1; j<=n; j++) if(map[k][j]) map[i][j] = 1; } 之前做了不少图论,图论周感觉能应付的过去. 14059727 247 Calling Circles Accepted C++ 0.0

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

链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=183 题意: 如果两个人相互打电话(直接或间接),则说他们在同一个电话圈里.例如,a打给b,b打给c,c打给d,d打给a,则这4个人在同一个圈里:如果e打给f但f不打给e,则不能推出e和f在同一个电话圈里.输入n(n≤25)个人的m次电话,找出所有电话圈.人名只包含字母,不超过25个

电话圈(floyd)

题意: 如果两个人相互打电话,则说他们在同一个电话圈里.例如,a打给b,b打给c,c打给d,d打给a,则这4个人在同一个圈里:如果e打给f但f不打给e,则不能推出e和f在同一个电话圈里,输出所有电话圈. //floyd求传递闭包,dfs求出电话圈: 1 #include<iostream> 2 #include<cstdio> 3 #include<cstdlib> 4 #include<cstring> 5 #include<vector> 6

UVa 247 (传递闭包) Calling Circles

题意: 有n个人m通电话,如果有两个人相互打电话(直接或间接)则在同一个电话圈里.输出所有电话圈的人的名单. 分析: 根据打电话的关系,可以建一个有向图,然后用Warshall算法求传递闭包. 最后输出是辅助一个标记数组,用DFS输出的,这个办法挺巧妙的. 本来我原来的想法是,用并查集求所有的连通分量,然后再好多次循环找连通分量一致的名字输出,那样太麻烦了. ios::sync_with_stdio(false);这个最好不要随便用,可能会产生某些副作用. 字符指针是可以传给string对象作参

uva_247_Calling Circles(floyd传递闭包)

Calling Circles Time Limit: 3000MS   Memory Limit: Unknown   64bit IO Format: %lld & %llu Submit Status Description If you've seen television commercials for long-distance phone companies lately, you've noticed that many companies have been spending

POJ 2594 —— Treasure Exploration——————【最小路径覆盖、可重点、floyd传递闭包】

Treasure Exploration Time Limit:6000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit Status Practice POJ 2594 Description Have you ever read any book about treasure exploration? Have you ever see any film about treasure exploratio

poj 2400 Supervisor, Supervisee KM求二分图+dfs输出所有解

题意: 有n个Supervisor和Supervisee,他们之间相互有一个评分,现在要求一个匹配,所有人的评分和最小,并输出使评分和最小的所有匹配方案. 分析: KM算法求二分图的最小权匹配,并用dfs输出所有方案. 代码: //poj 2400 //sep9 #include <iostream> using namespace std; const int maxN=16; char g[maxN][maxN]; int mx[maxN],my[maxN],hx[maxN],hy[max