《算法导论》习题解答 Chapter 22.1-4(去除重边)

思路:重开一个新图,按着邻接列表的顺序从上到下遍历,每遍历一行链表前,清空visited数组,如果没有访问过这个元素,则加入新图,如果已经访问过了(重边),则不动。

伪代码:

复杂度:O(V+E)

for each u 属于 Vertex
    visited[u] = false;
for u 属于 Vertex
	visited[u] = true;
	for v 属于 Adj[u]
		if(!visited[v])
			Adj1[u].insert(v);
			visited[v] = true;
	for v 属于 Adj[u]
            visited[v]=false;
        visited[u] = false;


证明算法正确性:


命题:给定一条边(u,v),此边为有向边,visited[v]=false 当且仅当 (u,v)需加入E'.

=>已知起点为u,visited[v]=false,则说明v曾经并没有被u访问到,因为如果访问到,则visited[v]被置为true,则如果当访问边(u,v)时,visited[v]==false,则会将(u,v)加入E'中.
<=已知(u,v)需要加入E',如果visited[v]=true,则不会执行if里的语句,则说明(u,v)不会加入E',与条件矛盾。


输入:

3 8
a b
a b
a b
b c
b c
b c 
c a
c c


源代码:

package C22;

import java.util.Iterator;
/**
 * 化简多重图
 * @author xiazdong
 *
 */
public class C1_4 {
	static Adjacent_List g;
	public static void main(String[] args) throws Exception {
		Adjacent_List adjacent_list = GraphFactory.getAdjacentListInstance("input\22.1-4.txt");	
		C1_4.g = adjacent_list;
		Adjacent_List new_adj = remove_multiedge(adjacent_list);
		adjacent_list.printAllEdges();
		System.out.println("==============");
		new_adj.printAllEdges();
	}
	/**
	 * 去掉重边的函数
	 * @param g
	 * @return
	 */
	public static Adjacent_List remove_multiedge(Adjacent_List g){
		int size = g.getSize();
		Adjacent_List adj1 = new Adjacent_List(size);
		boolean visited[] = new boolean[size];
		for(int i=0;i<visited.length;i++) visited[i] = false;//O(V)
		for(int i=0;i<size;i++){		//O(V+E)
			visited[i] = true;
			Iterator<String> iter = g.getListByVertexIndex(i).iterator();
			while(iter.hasNext()){	
				String vstr = iter.next();
				int v = g.getVertexIndex(vstr);
				if(!visited[v]){
					visited[v] = true;
					adj1.addEdge(g.getVertexValue(i), vstr);
				}
			}
			/*下面一句话 对新图遍历比较快,虽然速度只会提升常数级别。
			 较快:iter = adj1.getListByVertexValue(g.getVertexValue(i)).iterator();
			 较慢:iter = g.getListByVertexIndex(i).iterator(); 因为重边
			 */
			iter = adj1.getListByVertexValue(g.getVertexValue(i)).iterator();	
			while(iter.hasNext()){	//再一次遍历这个链表,并对这些元素清除数组 O(E)
				String vstr = iter.next();
				int v = g.getVertexIndex(vstr);
				visited[v] = false;
			}
			visited[i] = false;
		}
		return adj1;
	}
}


原文点此索引目录。感谢xiazdong君 && Google酱。这里是偶尔做做搬运工的水果君(^_^) )

原文地址:https://www.cnblogs.com/java20130723/p/3212123.html