木其网络科技专业程序员代写http://www.xmsydw.com
程序员学历擅长经验网店链接
apenny硕士ASP.NET PHP 电子 通信设计 图像 编程 网络5年进入店铺
zheng_qianqian本科C语言 C++面向对象 Java5年进入店铺
guoguanl本科Java Web项目 JSP Hibernate Struts Mysql5年进入店铺

《算法导论》习题解答 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_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酱。这里是偶尔做做搬运工的水果君(^_^) )

posted @ 2013-07-17 00:49  程序流程图  阅读(453)  评论(0编辑  收藏  举报
木其网络科技专业程序员代写http://www.xmsydw.com
程序员学历擅长经验网店链接
apenny硕士ASP.NET PHP 电子 通信设计 图像 编程 网络5年进入店铺
zheng_qianqian本科C语言 C++面向对象 Java5年进入店铺
guoguanl本科Java Web项目 JSP Hibernate Struts Mysql5年进入店铺