思路:设置两个游标i指向行,j指向列,如果arr[i][j]==1,则i=max{i+1,j},j++;如果arr[i][j]==0,则j=max{i+1,j+1}。

伪代码:

has_universal_sink()
for i=1 to N //对角线检查是否全是0
if A[i][i]==1 return false;
i=1,j=2
while(i<=N && j<=N)
if(A[i][j]==1)
i=max{i+1,j}
j++
else
j=max{i+1,j+1}
if i<=N
if check arr[i][*]=0,arr[*(except i)][i]=1 return true;
else return false;
else
return false;

命题:如果A[i][j]=0,则j不是通用汇点。

因为A[i][j]=0,说明i到j没有边,而通用汇点的定义是一定要每个点都要有一条指向他的边,因此j不是通用汇点。



命题:如果A[i][j]=1,则i不是通用汇点。

因为A[i][j]=1,所以i到j有一条边,所以i不是通用汇点。



循环不变式:每次迭代前,i之前和j之前但不包括i的点都不是通用汇点。

初始:i=1,j=2,i之前为空,j之前但不包括i的点也为空,因此成立。

保持:在迭代开始时,已知i之前和j之前但不包括i的点都不是通用汇点,当进入循环体后,如果A[i][j]==1,则说明i肯定不是通用汇点,并且已知j之前不包括i的点不是通用汇点,因此i=max{i+1,j},j++后仍然保持不变式;如果A[i][j]==0,则j不是通用汇点,如果j原本小于i,则j要到i+1,因为已知i之前的点肯定不是通用汇点,所以现在仍然保持不变式成立。

终止:如果i<=N,j=N+1,j之前除了i其他点都不是通用汇点,因此需要去全面检查i是不是通用汇点。如果i=N+1,则不需要检查了,没有通用汇点。



命题:如果A[i][j]=1,则j之前的点都不是通用汇点。



命题:如果A[i][j]=0,则i之前的点都不是通用汇点。

输入:

4 3

a c

b c

d c

源代码:

package C22;

import java.io.ObjectInputStream.GetField;

/**
* 此处提供两种方法,一种是网上的方法,一种是自己想的方法,
* 经过测试,如果同时执行100000000次,则网上的方法速度是3.6秒,我的方法速度是3秒
* @author xiazdong
*
*/
public class C1_6 {
private static int sink_index = -1;
public static void main(String[] args) throws Exception {
Adjacent_Matrix adj_matrix = GraphFactory.getAdjacentMatrixInstance("input\\22.1-6.txt");
boolean flag = has_universal_sink(adj_matrix);
if(flag)System.out.println(adj_matrix.getVertexValue(sink_index));
}
/**
* 自己的方法
* @return
*/
public static boolean has_universal_sink(Adjacent_Matrix g){
int i=0,j=0;
boolean flag = true;
while(j<=g.getSize()-1){
if(g.getElement(i, j)==1){
i = j;
}
j++;
}
//检查arr[i][*]==0 arr[*(except i)][i]==1
for(int a=0;a<g.getSize();a++){
if(g.getElement(i, a)==1&&i!=a){
flag = false;
}
if(g.getElement(a, i)==0&&i!=a){
flag = false;
}
}
if(flag) sink_index = i;
return flag;
}
/**
* 网上的方法
* @return
*/
public static boolean has_universal_sink2(Adjacent_Matrix g){
int i=0,j=0;
boolean flag = true;
while(j<=g.getSize()-1){
if(g.getElement(i, j)==1){
i++;
}
else
j++;
}
//检查arr[i][*]==0 arr[*(except i)][i]==1
for(int a=0;a<g.getSize();a++){
if(g.getElement(i, a)==1&&i!=a){
flag = false;
}
if(g.getElement(a, i)==0&&i!=a){
flag = false;
}
}
if(flag) sink_index = i;
return flag;
}
}

这边还有一篇跟通用汇点有关的博文,说实话,通用汇点的o(v)的求法我还不是搞的很懂,有空值得研究一下。

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

《算法导论》习题解答 Chapter 22.1-6(求universal sink 通用汇点)的更多相关文章

  1. 《算法导论》习题解答 Chapter 22.1-5(求平方图)

    一.邻接矩阵实现 思路:如果是邻接矩阵存储,设邻接矩阵为A,则A*A即为平方图,只需要矩阵相乘即可: 伪代码: for i=1 to n for j=1 to n for k=1 to n resul ...

  2. (搬运)《算法导论》习题解答 Chapter 22.1-1(入度和出度)

    (搬运)<算法导论>习题解答 Chapter 22.1-1(入度和出度) 思路:遍历邻接列表即可; 伪代码: for u 属于 Vertex for v属于 Adj[u] outdegre ...

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

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

  4. 《算法导论》习题解答 Chapter 22.1-8(变换邻接表的数据结构)

    一般散列表都与B+树进行比较,包括在信息检索中也是. 确定某条边是否存在需要O(1). 不足: (1)散列冲突. (2)哈希函数需要不断变化以适应需求. 另外:B+树.(见第18章) 与散列表相比的不 ...

  5. 《算法导论》习题解答 Chapter 22.1-7(关联矩阵的性质)

    主对角线:出度+入度 其他:arr[i][j]=-n,则i与j之间有n条边. 证明: (原文点此,索引目录.感谢xiazdong君 && Google酱.这里是偶尔做做搬运工的水果君( ...

  6. 《算法导论》习题解答 Chapter 22.1-3(转置图)

    一.邻接表实现 思路:一边遍历,一边倒置边,并添加到新的图中 邻接表实现伪代码: for each u 属于 Vertex for v 属于 Adj[u] Adj1[v].insert(u); 复杂度 ...

  7. 《算法导论》习题解答 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 ...

  8. C++ Primer(第五版)读书笔记 & 习题解答 --- Chapter 3

    Chapter 3.1 1. using声明具有如下的形式: using namespace::name; Chapter 3.2 1. C++标准一方面对库类型所提供的操作做了规定,另一方面也对库的 ...

  9. C++ Primer(第五版)读书笔记 & 习题解答 --- Chapter 2

    Chapter 2.1 1. 数据类型决定了程序中数据和操作的意义. 2. C++定义了一套基本数据类型,其中包括算术类型和一个名为void的特殊类型.算术类型包含了字符.整型.布尔值以及浮点数.vo ...

随机推荐

  1. 获取父进程ID

    本程序主要功能是:获取某程序的ParentProcessID 直接上代码: // parent.cpp (Windows NT/2000) // // This example will show t ...

  2. (剑指Offer)面试题33:把数组排成最小的数

    题目: 输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个.例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323. 思路: 1.全 ...

  3. springmvc中forward和redirect

    一.跳转 import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; im ...

  4. USB DATA Toggle

    For bulk and interrupt transfers, the data toggle resets <0> only on Set Configuration, Set In ...

  5. C++学习笔记之友元

    一.引言 C++控制对类对象私有部分(private)的访问,通常只能通过公有的(public)类方法去访问.但是有时候这种限制太严格,不适合特定的问题,于是C++提供了另外一种形式的访问权限:友元. ...

  6. Codeforces Round #337 (Div. 2) B. Vika and Squares 贪心

    B. Vika and Squares 题目连接: http://www.codeforces.com/contest/610/problem/B Description Vika has n jar ...

  7. .net+mssql制作抽奖程序思路及源码

    近期一直在研究数据库,刚好有个项目要做抽奖程序,恩,拿来练练手吧. 抽奖程序: 思路整理,无非就是点一个按钮,然后一个图片旋转一会就出来个结果就行了,可这个程序的要求不是这样的,是需要从数据库中随机抽 ...

  8. Android Compatibility package 兼容性开发套件

    我们认为Android 3.0平板电脑操作系统在美国时间2011年2月22日的正式推出,对于Android手机应用程序开发者所象征的意涵是: 之前大家所开发过的Android手机应用,除了可以在And ...

  9. [Angular2 Router] CanActivate Route Guard - An Example of An Asynchronous Route Guard

    In this tutorial we are going to learn how we can to configure an can activate route guard in the An ...

  10. dwr2反推

    package services; import org.directwebremoting.Browser; import org.directwebremoting.ScriptSessions; ...