• Algorithm: 拓扑排序


    摘自百度:对一个有向无环图(Directed Acyclic Graph简称DAG)G进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若 ∈E(G),则u在线性序列中出现在v之前。

    方法:

    拓扑排序方法如下:
    (1)从有向图中选择一个没有前驱(即入度为0)的顶点并且输出它.
    (2)从网中删去该顶点,并且删去从该顶点发出的全部有向边.
    (3)重复上述两步,直到剩余的网中不再存在没有前趋的顶点为止.
     
    例子:poj1094
     
    解法: 摘自http://www.cnblogs.com/pushing-my-way/archive/2012/08/23/2652033.html

    题意:给你一些大写字母间的偏序关系,然后让你判断能否唯一确定它们之间的关系,或者所给关系是矛盾的,或者到最后也不能确定它们之间的关系。

    分析:

    用拓扑排序:

    1.拓扑排序可以用栈来实现,每次入栈的是入度为0的节点。

    1.拓扑排序的结果一般分为三种情况:1、可以判断 2、有环出现了矛盾 3、条件不足,不能判断.

    2.这道题不仅需要判断这三种情况,而且还要判断在处理第几个关系时出现前两种情况,对于本道题来说三种情况是有优先级的。前两种情况是平等的谁先出现先输出谁的相应结果,对于第三种情况是在前两种情况下都没有的前提下输出相应结果的.

    网上对于这道题的错误提示:

    1.本题顺序:

    a.先判有没有环,有环就直接输出不能确定;

    b.如果没有环,那么就看会不会有多种情况,如果有多种情况就再读下一行;如果全部行读完还是有多种情况,就是确定不了;

    c.如果最后没有环,也不存在多种情况(即每次取出来入度为零的点只有一个),那么才是答案;

    2.有答案就先出答案,不管后面的会不会矛盾什么的;

    3.如果在没有读完所有输入就能出答案,一定要把剩下的行都读完。

     1 View Code 
     2  #include <iostream>
     3  #include <stdio.h>
     4  #include <string.h>
     5  #include <stack>
     6  using namespace std;
     7  //toposort的三种情况
     8  //188K 0MS
     9  const int N=27;
    10  int n,m;
    11  int graph[N][N],indegree[N],list[N];
    12  
    13  int toposort(int n)
    14  {
    15      int in[N];
    16      memcpy(in,indegree,sizeof(indegree)); //复制入度数组,以免对主函数中的indegree有影响
    17      stack<int> s;
    18      int i;
    19      for(i=0;i<n;i++)
    20          if(!in[i])
    21              s.push(i);//所有入度为0的点入栈,如果这些点多于1的话,序列不确定
    22      int flag=0;
    23      int t,j=0;
    24      while(!s.empty())
    25      {
    26          if(s.size()>1)
    27              flag=1;    //序列不确定
    28          t=s.top();
    29          s.pop();
    30          list[j++]=t;   //记录出栈的数字
    31          for(i=0;i<n;i++)
    32              if(graph[t][i])
    33                  if(--in[i]==0)
    34                      s.push(i);//入度为0的点入栈
    35      }
    36      if(j!=n)//不能拓扑排序,即有环
    37          return 1;
    38      else if(flag==1)//有多种排序方式,不能唯一确定
    39          return 2;
    40      return 0;//序列能够被唯一确定
    41  }
    42  
    43  int main()
    44  {
    45      int determined,inconsistency;
    46      int i,j,res;
    47      char a,b;
    48      while(scanf("%d%d",&n,&m) && n!=0 && m!=0)
    49      {
    50          getchar();
    51          determined=0;
    52          inconsistency=0;
    53          memset(graph,0,sizeof(graph));
    54          memset(indegree,0,sizeof(indegree));
    55          for(i=1;i<=m;i++)
    56          {
    57              scanf("%c<%c",&a,&b);
    58              getchar();
    59              if(!determined && !inconsistency)
    60              {
    61                  if(graph[b-'A'][a-'A']==1)//存在反向边,则发现矛盾
    62                  {
    63                      inconsistency=1;
    64                      printf("Inconsistency found after %d relations.\n",i);
    65                      continue;
    66                  }
    67                  if(graph[a-'A'][b-'A']==0)
    68                  {
    69                      graph[a-'A'][b-'A']=1;
    70                      indegree[b-'A']++;
    71                  }
    72                  res=toposort(n);//toposort
    73                  if(res==0)//序列能够被唯一确定
    74                  {
    75                      printf("Sorted sequence determined after %d relations: ",i);
    76                      for(j=0;j<n;j++)
    77                          printf("%c",list[j]+'A');
    78                      printf(".\n");
    79                      determined=1;
    80                  }
    81                  else if(res==1)//不能拓扑排序,即有环,发现矛盾
    82                  {
    83                      printf("Inconsistency found after %d relations.\n",i);
    84                      inconsistency=1;
    85                  }
    86              }
    87  
    88          }
    89          if(!determined && !inconsistency)//既没有唯一确定,也没发现矛盾(有环),即不能确定
    90              printf("Sorted sequence cannot be determined.\n");
    91      }
    92      return 0;
    93  }
    View Code
  • 相关阅读:
    OSPF网络类型
    OSPFDBD报文同步
    OSPF多区域设计原因及其原则
    OSPF一类LSA的linktype类型
    【虚拟化数据恢复】KVM虚拟机误删除数据恢复案例
    【虚拟机数据恢复】使用碎片拼接技术恢复XenServer服务器被删除的虚拟机的数据恢复案例
    【数据库数据恢复】Oracle数据库误truncate table的数据恢复案例
    Proj CMI Paper Reading: ModelBased GreyBox Fuzzing of Network Protocols
    Proj CMI Paper Reading: Mining Operational Preconditions
    Proj CMI Paper Reading: Predicting Patch Correctness Based on the Similarity of Failing Test Cases
  • 原文地址:https://www.cnblogs.com/yingzhongwen/p/3130516.html
Copyright © 2020-2023  润新知