题意
N个人,打了M次电话。假设M次电话为边,N个人为点,双向连通的点构成一个电话圈。求所有的电话圈。
题解
先用Flyod算法求出两个点之间是否连通,再用DFS求出电话圈。
代码
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Scanner;
public class Main{
public static void floyd(boolean d[][],int n) {
for(int k=0;k<n;k++){
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
d[i][j]=d[i][j]||(d[i][k]&&d[k][j]);
}
}
}
}
public static void dfs(int u,int n,boolean d[][],boolean vis[],Map<String, Integer> map,List<String> list) {
for(Entry<String, Integer> entry:map.entrySet()){
if(entry.getValue()==u){
list.add(entry.getKey());
break;
}
}
for(int i=0;i<n;i++){
if(d[u][i]&&d[i][u]){
if(!vis[i]){
vis[i]=true;
dfs(i, n, d, vis, map,list);
}
}
}
}
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
int kase=1;
while(scanner.hasNext()){
boolean d[][]=new boolean[50][50];
boolean vis[]=new boolean[50];
int n=scanner.nextInt();
int m=scanner.nextInt();
if(n+m==0)
break;
System.out.println("Calling circles for data set "+kase+":");
kase++;
Map<String, Integer> map=new HashMap<String,Integer>();
int cnt=0;
for(int i=0;i<m;i++){
String stra=scanner.next();
String strb=scanner.next();
if(!map.containsKey(stra)){
map.put(stra, cnt++);
}
if(!map.containsKey(strb)){
map.put(strb, cnt++);
}
d[map.get(stra)][map.get(strb)]=true;
}
for(int i=0;i<50;i++){
d[i][i]=true;
}
floyd(d,n);
for(int i=0;i<n;i++){
if(!vis[i]){
List<String> list=new ArrayList<String>();
vis[i]=true;
dfs(i, n, d, vis, map,list);
for(int j=0;j<list.size();j++){
if(j==list.size()-1){
System.out.print(list.get(j));
}else{
System.out.print(list.get(j)+", ");
}
}
System.out.println();
}
}
}
}
}