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

  • 相关阅读:
    HTTP基础
    DHCP(六)
    DOM备忘录
    正则表达式备忘录
    Function与Object的关系
    模块模式浅析
    视频下载
    JSP基础点滴
    迭代输出总结
    中文乱码问题的解决途径
  • 原文地址:https://www.cnblogs.com/java20130723/p/3212117.html
Copyright © 2020-2023  润新知