zoukankan      html  css  js  c++  java
  • 【原】 POJ 1094 Sorting It All Out 拓扑排序 解题报告

    http://poj.org/problem?id=1094

    方法:
    每加入一条边就进行一次拓扑排序,从而找到符合条件的最少边数
    拓扑排序的基本思想就是依次找到图中入度为0的节点,将该节点和其对应的边删除,这样就使得它的邻接节点的入度-1。反复循环这样做直到所有节点都从图中删除(都被编上拓扑编号),或者因为有环所以还剩下某些节点未被删除

    Description

    An ascending sorted sequence of distinct values is one in which some form of a less-than operator is used to order the elements from smallest to largest. For example, the sorted sequence A, B, C, D implies that A < B, B < C and C < D. in this problem, we will give you a set of relations of the form A < B and ask you to determine whether a sorted order has been specified or not.

    Input

    Input consists of multiple problem instances. Each instance starts with a line containing two positive integers n and m. the first value indicated the number of objects to sort, where 2 <= n <= 26. The objects to be sorted will be the first n characters of the uppercase alphabet. The second value m indicates the number of relations of the form A < B which will be given in this problem instance. Next will be m lines, each containing one such relation consisting of three characters: an uppercase letter, the character "<" and a second uppercase letter. No letter will be outside the range of the first n letters of the alphabet. Values of n = m = 0 indicate end of input.

    Output

    For each problem instance, output consists of one line. This line should be one of the following three:
    Sorted sequence determined after xxx relations: yyy...y.
    Sorted sequence cannot be determined.
    Inconsistency found after xxx relations.
    where xxx is the number of relations processed at the time either a sorted sequence is determined or an inconsistency is found, whichever comes first, and yyy...y is the sorted, ascending sequence.

    Sample Input

    4 6

    A<B

    A<C

    B<C

    C<D

    B<D

    A<B

    3 2

    A<B

    B<A

    26 1

    A<Z

    0 0

    Sample Output

    Sorted sequence determined after 4 relations: ABCD.

    Inconsistency found after 2 relations.

    Sorted sequence cannot be determined.

       1:  
       2: #include <stdio.h>
       3: #include <iostream>
       4: #include <queue>
       5: #include <set>
       6: #include <vector>
       7: #include <string>
       8: #include <fstream>
       9:  
      10: using namespace std ;
      11:  
      12: const int N=26 ;
      13: typedef vector< vector<char> > Graph ;
      14:  
      15: void run1094()
      16: {
      17:     //ifstream in("in.txt") ;
      18:  
      19:     Graph G ;
      20:     set<char> vertexSet ;
      21:  
      22:     int n,m ;
      23:     int relnum ;
      24:     int i,cnt ;
      25:     bool sucFlag,cyFlag,notdeterFlag ;
      26:     char s,t,vertex ;
      27:     
      28:     set<char>::iterator sIter ;
      29:     vector<char>::iterator vIter ;
      30:  
      31:     //while( scanf( "%d%d", &n,&m ) && n!= 0 )
      32:     while(cin>>n>>m && n!=0)
      33:     {
      34:         vertexSet.clear() ;  //一定注意使用容器前要clear
      35:         G.clear() ;
      36:         G.resize(N) ;
      37:         string *relation = new string[m] ;
      38:         int indegree[N] = {0} ;
      39:         int tmpIndegree[N]= {0} ;
      40:         char topnum[N] = {0} ;
      41:  
      42:         sucFlag = false ;
      43:         cyFlag = false ;
      44:  
      45:         i = 0 ;
      46:         while( i < m )
      47:             cin>>relation[i++] ;
      48:  
      49:         //对关系数从1~m枚举,每次往图中增加一条边而得到一个新图,对该图拓扑排序以找到符合条件的最小的关系数(边数)
      50:         for( relnum=1 ; relnum<=m ; ++relnum )
      51:         {
      52:             notdeterFlag = false ;  //***每次循环需要将其初始化
      53:  
      54:             queue<char> Q ;
      55:             for( i=0 ; i<n ; ++i )
      56:                 topnum[i] = 0 ;
      57:  
      58:             //得到此时的图的邻接表,vertexSet中存放的是当前图中的节点
      59:             s = relation[relnum-1][0] ;
      60:             t = relation[relnum-1][2] ;
      61:             vertexSet.insert(s) ;
      62:             vertexSet.insert(t) ;
      63:             G[s-'A'].push_back(t) ;  //更新邻接表
      64:             ++indegree[t-'A'] ;      //更新indegree
      65:  
      66:             for( i=0 ; i<N ; ++i )
      67:                 tmpIndegree[i] = indegree[i] ;  //复制此时的indegree,因为需要改变此数组
      68:  
      69:             //找到初始时入度为0的vertex
      70:             for( sIter=vertexSet.begin() ; sIter!=vertexSet.end() ; ++sIter )
      71:             {
      72:                 if( tmpIndegree[*sIter-'A']==0 )
      73:                     Q.push(*sIter) ;
      74:             }
      75:             //任何时刻当入度为0的vertex多于1个时,则拓扑排序的结果不唯一
      76:             //此时将notdeterFlag置为true表示该暂时图的拓扑结果不唯一
      77:             if( Q.size() > 1 )
      78:                 notdeterFlag = true ;
      79:  
      80:             //循环进行拓扑排序
      81:             cnt = 0 ;
      82:             while( !Q.empty() )
      83:             {
      84:                 vertex = Q.front() ;
      85:                 Q.pop() ;
      86:                 topnum[cnt++] = vertex ;  //分配拓扑排序编号
      87:  
      88:                 //将需要从图中删除的节点的边也删除掉,这意味着它的所有邻接点的入度-1
      89:                 for( vIter=G[vertex-'A'].begin() ; vIter!=G[vertex-'A'].end() ; ++vIter )
      90:                 {
      91:                     //所有邻接点的入度-1,并将入度减为0的节点入队等待分配拓扑排序编号
      92:                     if( --tmpIndegree[*vIter-'A'] == 0 )
      93:                         Q.push(*vIter) ;
      94:                 }
      95:                 //任何时刻当入度为0的vertex多于1个时,则拓扑排序的结果不唯一
      96:                 if( Q.size() > 1 )
      97:                     notdeterFlag = true ;
      98:             }
      99:  
     100:             //若该暂时图所有节点还没有全部被排序,就已经找不出入度为0的节点了,则证明该图有环
     101:             //跳出判断循环并输出结果“有环”
     102:             if( cnt!=vertexSet.size() )
     103:             {
     104:                 cyFlag = true ;
     105:                 break ;
     106:             }
     107:  
     108:             //若该图已被排序,并且排序结果唯一(由notdeterFlag为false决定)
     109:             //同时被排序的节点数等于完整图中的所有节点的个数
     110:             //跳出判断循环并输出结果“可以唯一地排序”
     111:             if( !notdeterFlag && cnt==n )
     112:             {
     113:                 sucFlag = true ;
     114:                 break ;
     115:             }
     116:         }
     117:         delete []relation ;
     118:  
     119:         if( sucFlag )
     120:         {
     121:             printf( "Sorted sequence determined after %d relations: " , relnum );
     122:             for( i=0 ; i<n ; ++i )
     123:                 printf( "%c" , topnum[i] ) ;  //输出char用%c
     124:             printf( ".\n" ) ;
     125:         }
     126:         else if( cyFlag )
     127:             printf( "Inconsistency found after %d relations.\n" , relnum ) ;
     128:         else if( notdeterFlag )
     129:             printf( "Sorted sequence cannot be determined.\n" ) ;        
     130:     }
     131: }

    如果您满意我的博客,请点击“订阅Allen Sun的技术博客”即可订阅,谢谢:)

    原创文章属于Allen Sun
    欢迎转载,但请注明文章作者Allen Sun和链接
  • 相关阅读:
    LeetCode 12. 整数转罗马数字
    [Python] for in range()使用以及列表字符串反转方法
    组合数问题
    「BJOI2020」封印
    数据结构优化建图
    小Q与找茬
    无旋Treap学习
    jzoj5679
    数星星
    凸性
  • 原文地址:https://www.cnblogs.com/allensun/p/1869414.html
Copyright © 2011-2022 走看看