zoukankan      html  css  js  c++  java
  • 拓扑编号 vijos1790

    题意就是拓扑排序,要求1的序号尽可能小,然后2的序号尽可能小,3,4...

     

    一开始很容想到直接贪心,每次选一个入度为0的点,如果有多个,就选编号最小的那个,但是很容易找到反例。

    看了下题解,应该是反着做拓扑排序,每次取编号最大的,但是没有人给出证明。下面给出我的证明,欢迎指出错误。

    ps:参考了一位大牛的文章,poj有一道题类似,参考了他的题解,但是找不到了,所以没法放出他的链接了,先道歉。


    假设我们按逆拓扑排序的方法求出了一个拓扑序列(把得到的反序列正过来),记为A。


    假设最优解的拓扑序列是B。


    从后往前比较AB,设在位置k,AB第一次出现不同。即A[k]!=B[k],A[p]=B[p].


    显然根据我们的贪心策略"每次取的是编号最大的",有A[k]>B[k].


    那么我们在B中取寻找A[k],即找到B[p]=A[k].


    然后把B中B[p],B[p+1]...B[k]这一段拿出来,记为序列C。


    因为B[p]=A[k] , 把B[p]换成A[k],C=A[k],B[p+1]....B[k].


    很显然在C中A[k]不是最小的,因为至少B[k]比它小。 假设C中最小的是B[q],那么我们可以构造出一个序列D.


    D=B[p+1],B[p+2]...B[q],A[k],B[q+1]...B[k]. (实质就是把A[k]移到B[q]的后面)


    显然这个序列会比序列C更优,因为B[q]的名次靠前了一名。 那么如果把C换成D会更优,与B是最优解矛盾。


    那么怎么知道序列D一定是合法的呢?因为如果A[k]恰好是B[p+1]的前驱,那么就不能把A[k]移走。


    所以我们回到序列A,序列A中A[k]是AB序列从右往左第一个不同的元素,那么在A中,B[p+1]肯定是在A[k]前面的,所以A[k]不可能是B[p+1]的前驱。


    综上,我们得到的答案就是最优解。 

  • 相关阅读:
    ORACLE设置用户密码不过期
    oracle错误(ORA:12154 ORA:01034 和 ORA:27101 ORA-18008 ORA-01081)
    常用正则表达式整理
    JS中处理单个反斜杠(即转义字符的处理)
    SpringMVC 使用PUT请求遇到的问题小结
    Tomcat7 目录详解
    java对象之----(PO,VO,DAO,BO,POJO)
    Oracle使用触发器和mysql中使用触发器的比较
    Oracle 数据库中对记录进行分页处理
    PHPOffice下PHPWord生成Word2007(docx)使用方法
  • 原文地址:https://www.cnblogs.com/vb4896/p/4083650.html
Copyright © 2011-2022 走看看