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

Posted hkxy125

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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求出传递闭包,即G[i][j]表示i是否直接或者间接给j打过电话。
则当且仅当G[i][j]=G[j][i]=true时二者处于一个电话圈。
依此结论直接判断输出即可。

 

代码:

 1 import java.io.*;
 2 import java.util.*;
 3 import static java.util.Arrays.*;
 4 
 5 public class Main {
 6     Scanner cin = new Scanner(new BufferedInputStream(System.in));
 7     final int UP = 25 + 5;
 8     boolean vis[] = new boolean[UP], G[][] = new boolean[UP][UP];
 9     ArrayList<String> name = new ArrayList<String>();
10     
11     int id(String s) {
12         for(int i = 0; i < name.size(); i++) {
13             if(name.get(i).equals(s)) return i;
14         }
15         name.add(s);
16         return name.size() - 1;
17     }
18     
19     void MAIN() {
20         for(int cases = 1; ; cases++) {
21             int n = cin.nextInt();
22             int m = cin.nextInt();
23             if(n == 0 && m == 0) break;
24             name.clear();
25             for(int t = 0; t < n; t++)
26                 for(int i = 0; i < n; i++) G[t][i] = false;
27             for(int i = 0; i < m; i++)
28                 G[id(cin.next())][id(cin.next())] = true;
29             
30             for(int i = 0; i < n; i++) G[i][i] = true;
31             for(int k = 0; k < n; k++) {
32                 for(int i = 0; i < n; i++) {
33                     for(int j = 0; j < n; j++) G[i][j] |= G[i][k] & G[k][j];
34                 }
35             }
36             
37             if(cases > 1) System.out.println();
38             System.out.printf("Calling circles for data set %d:
", cases);
39             fill(vis, false);
40             for(int t = 0; t < n; t++) {
41                 if(vis[t]) continue;
42                 System.out.printf("%s", name.get(t));
43                 for(int i = t+1; i < n; i++) {
44                     if(G[t][i] && G[i][t]) {
45                         System.out.printf(", %s", name.get(i));
46                         vis[i] = true;
47                     }
48                 }
49                 System.out.println();
50             }
51         }
52     }
53     
54     public static void main(String args[]) { new Main().MAIN(); }
55 }

 







以上是关于UVa 247 - Calling Circles(Floyd求有向图的传递闭包)的主要内容,如果未能解决你的问题,请参考以下文章

uva247(floyd+dfs)

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

547. Friend Circles

LeetCode Friend Circles

text Diigs story circles.pde

text 与circles.pde有关