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.
#include <stdio.h>
#include <iostream>
#include <queue>
#include <set>
#include <vector>
#include <string>
#include <fstream>
9:
namespace std ;
11:
int N=26 ;
char> > Graph ;
14:
void run1094()
16: {
18:
19: Graph G ;
char> vertexSet ;
21:
int n,m ;
int relnum ;
int i,cnt ;
bool sucFlag,cyFlag,notdeterFlag ;
char s,t,vertex ;
27:
char>::iterator sIter ;
char>::iterator vIter ;
30:
while(cin>>n>>m && n!=0)
33: {
//一定注意使用容器前要clear
35: G.clear() ;
36: G.resize(N) ;
new string[m] ;
int indegree[N] = {0} ;
int tmpIndegree[N]= {0} ;
char topnum[N] = {0} ;
41:
42: sucFlag = false ;
43: cyFlag = false ;
44:
45: i = 0 ;
while( i < m )
47: cin>>relation[i++] ;
48:
//对关系数从1~m枚举,每次往图中增加一条边而得到一个新图,对该图拓扑排序以找到符合条件的最小的关系数(边数)
for( relnum=1 ; relnum<=m ; ++relnum )
51: {
//***每次循环需要将其初始化
53:
char> Q ;
for( i=0 ; i<n ; ++i )
56: topnum[i] = 0 ;
57:
//得到此时的图的邻接表,vertexSet中存放的是当前图中的节点
59: s = relation[relnum-1][0] ;
60: t = relation[relnum-1][2] ;
61: vertexSet.insert(s) ;
62: vertexSet.insert(t) ;
//更新邻接表
//更新indegree
65:
for( i=0 ; i<N ; ++i )
//复制此时的indegree,因为需要改变此数组
68:
//找到初始时入度为0的vertex
for( sIter=vertexSet.begin() ; sIter!=vertexSet.end() ; ++sIter )
71: {
'A']==0 )
73: Q.push(*sIter) ;
74: }
//任何时刻当入度为0的vertex多于1个时,则拓扑排序的结果不唯一
//此时将notdeterFlag置为true表示该暂时图的拓扑结果不唯一
if( Q.size() > 1 )
78: notdeterFlag = true ;
79:
//循环进行拓扑排序
81: cnt = 0 ;
while( !Q.empty() )
83: {
84: vertex = Q.front() ;
85: Q.pop() ;
//分配拓扑排序编号
87:
//将需要从图中删除的节点的边也删除掉,这意味着它的所有邻接点的入度-1
'A'].end() ; ++vIter )
90: {
//所有邻接点的入度-1,并将入度减为0的节点入队等待分配拓扑排序编号
'A'] == 0 )
93: Q.push(*vIter) ;
94: }
//任何时刻当入度为0的vertex多于1个时,则拓扑排序的结果不唯一
if( Q.size() > 1 )
97: notdeterFlag = true ;
98: }
99:
//若该暂时图所有节点还没有全部被排序,就已经找不出入度为0的节点了,则证明该图有环
//跳出判断循环并输出结果“有环”
if( cnt!=vertexSet.size() )
103: {
104: cyFlag = true ;
break ;
106: }
107:
//若该图已被排序,并且排序结果唯一(由notdeterFlag为false决定)
//同时被排序的节点数等于完整图中的所有节点的个数
//跳出判断循环并输出结果“可以唯一地排序”
if( !notdeterFlag && cnt==n )
112: {
113: sucFlag = true ;
break ;
115: }
116: }
delete []relation ;
118:
if( sucFlag )
120: {
, relnum );
for( i=0 ; i<n ; ++i )
//输出char用%c
) ;
125: }
if( cyFlag )
, relnum ) ;
if( notdeterFlag )
) ;
130: }
131: }