图的连通性的概念:

连通无向图:如果无向图任意两个顶点都连通,则称为连通无向图
连通有向图:如果有向图任意两个顶点vi,vj,从vi到vj和从vj到vi都有路径,则称有向图是强连通有向图



public class Connect {

public static void main(String[] args) {
Set<String> nodes = ImmutableSet.of("A", "B", "C", "D");
List<String> hop = Lists.newArrayList("C->A", "C->D");
List<Pair<String, String>> objects = Lists.newArrayList();
for (String s : hop) {
String[] split = s.split("->");
String from = split[0];
String to = split[1];
Pair<String, String> pair = new Pair<>(from, to);
objects.add(pair);
}
Boolean isConnect = unDirectGraphConnect(nodes,objects);
System.out.println("无向图连通性");
System.out.println(isConnect);
System.out.println("有向图连通性");
Boolean isConnect2 = directGraphConnect(nodes, objects);
System.out.println(isConnect2);
}

/**
* 连通无向图判断,最后应该只有一个连通分量,而且可以连通所有节点
*
* @param pairList
* @return
*/
public static Boolean unDirectGraphConnect(Set<String> nodes, List<Pair<String, String>> pairList) {
Multimap<String, String> map = HashMultimap.create();

for (Pair<String, String> pair : pairList) {
String from = pair.getFrom();
String to = pair.getTo();
//默认from、to都不存在
boolean fromPresent = false;
boolean toPresent = false;
if (isPresent(map, from)) {
fromPresent = true;
}
if (isPresent(map, to)) {
toPresent = true;
}
//from/to都不存在,最简单,from做key,将from和to放value里
if (!fromPresent && !toPresent) {
map.put(from, from);
map.put(from, to);
//from存在,to不存在,要区分from是key还是value
} else if (!toPresent) {
boolean inKey = map.containsKey(from);
if (inKey) {
map.put(from, to);
} else {
String valKey = getKeyByValue(map, from);
map.put(valKey, to);
}
//to存在,from不存在,也要区分to是key还是value
} else if (!fromPresent) {
boolean toInKey = map.containsKey(to);
if (toInKey) {
map.put(to, from);
} else {
String valKey = getKeyByValue(map, to);
map.put(valKey, from);
}
}
//剩下最后一种可能,from/to都存在,那就不需要处理了
}
System.out.println(map);
//只有一个连通分量,且能连通所有节点
return map.keySet().size() == 1 && map.values().containsAll(nodes);

}

/**
* 有向图连通性判断
* 理论上有多少顶点就有多少key,且value都等于顶点数
*
* @param pairList
* @return
*/
public static Boolean directGraphConnect(Set<String> nodes, List<Pair<String, String>> pairList) {
Multimap<String, String> map = HashMultimap.create();
//对map初始化
for (String node : nodes) {
map.put(node, node);
}

for (Pair<String, String> pair : pairList) {
String from = pair.getFrom();
String to = pair.getTo();

Collection<String> values = map.get(from);
//把to加入from连通map
if (!values.contains(to)) {
map.put(from, to);
}
//所有之前能到from的,现在也能到to了
for (String key : map.keySet()) {
Collection<String> values2 = map.get(key);
if (values2.contains(from) && !values2.contains(to)) {
values2.add(to);
}
}
//所有之前to能到的,现在from也能到了
Collection<String> value5 = map.get(to);
for (String s : value5) {
if (!map.get(from).contains(s)) {
map.put(from, s);
}
}


}
boolean connect = true;
int nodeSize = nodes.size();
for (String key : map.keySet()) {
Collection<String> values3 = map.get(key);
if (values3.size() != nodeSize) {
connect = false;
}
}
System.out.println(map);
return connect;

}
}