《算法导论》习题解答 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酱。这里是偶尔做做搬运工的水果君(^_^)
)
《算法导论》习题解答 Chapter 22.1-4(去除重边)的更多相关文章
- (搬运)《算法导论》习题解答 Chapter 22.1-1(入度和出度)
(搬运)<算法导论>习题解答 Chapter 22.1-1(入度和出度) 思路:遍历邻接列表即可; 伪代码: for u 属于 Vertex for v属于 Adj[u] outdegre ...
- 《算法导论》习题解答 Chapter 22.1-5(求平方图)
一.邻接矩阵实现 思路:如果是邻接矩阵存储,设邻接矩阵为A,则A*A即为平方图,只需要矩阵相乘即可: 伪代码: for i=1 to n for j=1 to n for k=1 to n resul ...
- 《算法导论》习题解答 Chapter 22.1-6(求universal sink 通用汇点)
思路:设置两个游标i指向行,j指向列,如果arr[i][j]==1,则i=max{i+1,j},j++:如果arr[i][j]==0,则j=max{i+1,j+1}. 伪代码: has_univers ...
- 《算法导论》习题解答 Chapter 22.1-8(变换邻接表的数据结构)
一般散列表都与B+树进行比较,包括在信息检索中也是. 确定某条边是否存在需要O(1). 不足: (1)散列冲突. (2)哈希函数需要不断变化以适应需求. 另外:B+树.(见第18章) 与散列表相比的不 ...
- 《算法导论》习题解答 Chapter 22.1-7(关联矩阵的性质)
主对角线:出度+入度 其他:arr[i][j]=-n,则i与j之间有n条边. 证明: (原文点此,索引目录.感谢xiazdong君 && Google酱.这里是偶尔做做搬运工的水果君( ...
- 《算法导论》习题解答 Chapter 22.1-3(转置图)
一.邻接表实现 思路:一边遍历,一边倒置边,并添加到新的图中 邻接表实现伪代码: for each u 属于 Vertex for v 属于 Adj[u] Adj1[v].insert(u); 复杂度 ...
- 《算法导论》习题解答 Chapter 22.1-2(邻接矩阵与链表)
链表如图: 矩阵: 1 2 3 4 5 6 7 1 0 1 1 0 0 0 0 2 1 0 0 1 1 0 0 3 1 0 0 0 0 1 1 4 0 1 0 0 0 0 0 5 0 1 0 0 0 ...
- C++ Primer(第五版)读书笔记 & 习题解答 --- Chapter 3
Chapter 3.1 1. using声明具有如下的形式: using namespace::name; Chapter 3.2 1. C++标准一方面对库类型所提供的操作做了规定,另一方面也对库的 ...
- C++ Primer(第五版)读书笔记 & 习题解答 --- Chapter 2
Chapter 2.1 1. 数据类型决定了程序中数据和操作的意义. 2. C++定义了一套基本数据类型,其中包括算术类型和一个名为void的特殊类型.算术类型包含了字符.整型.布尔值以及浮点数.vo ...
随机推荐
- Codeforces 711 C. Coloring Trees (dp)
题目链接:http://codeforces.com/problemset/problem/711/C 给你n棵树,m种颜色,k是指定最后的完美值.接下来一行n个数 表示1~n树原本的颜色,0的话就是 ...
- CodeForces 709B Checkpoints (数学,最短路)
题意:给定你的坐标,和 n 个点,问你去访问至少n-1个点的最短路是多少. 析:也是一个很简单的题,肯定是访问n-1个啊,那么就考虑从你的位置出发,向左访问和向右访问总共是n-1个,也就是说你必须从1 ...
- OpenSSL命令---ciphers
用途: 指令是用来展示用于SSL加密算法的工具.它能够把所有openssl支持的加密算法按照一定规律排列(一般是加密强度).这样可以用来做测试工具,决定使用什么加密算法. 用法: openssl ci ...
- java 对excel操作导入excel数据到数据库
加入jar包jxl.jar ===================services层掉用工具类==================================== // 导入 public Lis ...
- Oracle中wm_concat()函数的使用
Oracle中wm_concat()函数的使用 wm_concat()函数是oracle行列转换函数,该函数可以把列值以‘,’分割开来,并显示成一行. 1.原数据: 2.把结果分组以‘|’分隔,以一行 ...
- spring4 定时任务
一.spring 定时任务 spring 定时任务 ,最好使用quartz 实现.下面我以spring4为例 二.实战(默认) 1.pom配置 <!-- spring time task --& ...
- PHP操作MongoDB数据库
http://blog.csdn.net/sunboy_2050/article/details/49449319
- php写扩展
用PHP扩展做一个HelloWorld! PHP 尽管提供了大量有用的函数,但是在特殊情况下还可能需要进行扩展编程,比如大量的 PECL(PHP Extension Community Library ...
- TL-WR703 USB不稳定/当前的总结
http://see.sl088.com/wiki/WR703_USB%E4%B8%8D%E7%A8%B3%E5%AE%9A/%E5%BD%93%E5%89%8D%E7%9A%84%E6%80%BB% ...
- 编写一个JavaScript函数 parseQueryString,把URL参数解析为一个对象
var url="http://www.taobao.com/index.php?key0=0&key1=1&key2=2"; function parseQuer ...