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

  • 相关阅读:
    Leetcode 16.25 LRU缓存 哈希表与双向链表的组合
    Leetcode437 路径总和 III 双递归与前缀和
    leetcode 0404 二叉树检查平衡性 DFS
    Leetcode 1219 黄金矿工 暴力回溯
    Leetcode1218 最长定差子序列 哈希表优化DP
    Leetcode 91 解码方法
    Leetcode 129 求根到叶子节点数字之和 DFS优化
    Leetcode 125 验证回文串 双指针
    Docker安装Mysql记录
    vmware虚拟机---Liunx配置静态IP
  • 原文地址:https://www.cnblogs.com/java20130723/p/3212117.html
Copyright © 2011-2022 走看看