思路:
对于每一个case,每输入一个式子的时候都要判断一下这次的输入能否使当前case的n个字母有序,如果可以,不处理下面的输入。如何判断:构建图,初始每个顶点入度都为0,如果没有入度为0的点,说明有环,结束;如果目前输入的表达式含有的字母数没到n时,说明无序;否则看是否能建立拓扑排序,如果能输出拓扑排序结果;不能,输出cannot determined。
代码如下:
#include<iostream>
#include<fstream>
using namespace std;
int map[27][27];
int indegree[27],queue[27];
int toposort(int n)
{
int flag=1,m,loc,count=0;
int temp[27];
for (int i = 1; i <= n; i++)
{
temp[i] = indegree[i];
}
for (int i = 1; i <= n; i++)
{
m = 0;//入度为0的顶点个数
for (int j = 1; j <= n; j++)
{
if (temp[j] == 0)
{
m++;
loc = j;
}
}
if (m == 0) //没有入度为0的点,说明是环!
{
return 0;
}
if (m > 1) //入度为0的顶点个数>1,说明无序!
{
flag = -1;
}
queue[count++] = loc; //入度为0的顶点入队,每次去除一个入度为0的顶点
temp[loc] = -1;
for (int j = 1; j <= n; j++) //更新其它点入度信息
{
if (map[loc][j] == 1)
{
temp[j]--;
}
}
}
return flag;
}
int main()
{
//ifstream in("input.txt");
int n, m,success;
char str[5];
while (cin >> n >> m && n != 0 && m != 0)
{
memset(map,0,sizeof(map));
memset(indegree,0,sizeof(indegree));
success = 0;
for (int i = 1; i <= m; i++)
{
cin >> str;
if (success == 1)
continue;
int x = str[0] - 'A' + 1;
int y = str[2] - 'A' + 1;
map[x][y] = 1;
indegree[y]++;
int result = toposort(n);
if (result==0) //如果是环,找到结果,退出!
{
cout << "Inconsistency found after " <<i<<" relations."<< endl;
success = 1;
}
if (result == 1)
{
cout << "Sorted sequence determined after " << i << " relations: ";
for (int j = 0; j < n; j++)
{
char c = queue[j] + 'A' - 1;
cout << c;
}
cout <<"."<< endl;
success = 1;
}
}
if (success != 1)
{
cout << "Sorted sequence cannot be determined." << endl;
}
}
//system("pause");
return 0;
}