POJ1094 Sorting It All Out(拓扑排序)
题意:
字符拓扑排序,有三种可能的输出情况:
1.有环直接输出不能确定
2.如果所有的行都读入还是不能确定而且没有环
3.没有环而且没有多种情况(入度为0的点只有一个)就可以确定顺序
要点:
这题还是挺难的,主要是考察了拓扑排序的几种情况:1、可以判断 2、有环出现了矛盾 3、条件不足,不能判断。并且这道题用栈来做比较方便,dfs不太能判断是否只有一个解
还有如果中间已经满足了输出条件,直接输出并且改变标签,后面输入还是需要读入但已经输出结果了
15176284 | Seasonal | 1094 | Accepted | 148K | 16MS | C++ | 1729B | 2016-02-19 11:50:08 |
#include<stdio.h>
#include<string.h>
#include<stack>
using namespace std;
int n, m;
bool graph[50][50];
int indegree[50],list[50];
int toposort()
{
int temp[50];
memcpy(temp, indegree, sizeof(indegree));
stack<int> s;
for (int i = 0; i < n; i++)
if (!temp[i])
s.push(i);
int count = 0;
bool flag = false;
while (!s.empty())
{
if (s.size() > 1) //唯一确定时,入度为0的只有一个
flag = true;
int t = s.top();
s.pop();
list[count++] = t;
for (int i = 0; i < n; i++)
if (graph[t][i])
if (--temp[i] == 0)
s.push(i);
}
if (count != n)
return 0; //该有向图有回路,拓扑排列不存在
else if (flag)
return 2; //有多种排列方式
return 1; //排列有且只有一种
}
int main()
{
int i, j;
char a, b;
bool inconsistency, determined;
while (~scanf("%d%d", &n, &m), n + m)
{
getchar();
memset(graph, false, sizeof(graph));
memset(indegree, 0, sizeof(indegree));
inconsistency = false; determined = false;//一个判断是否有环,一个判断是否唯一确定
for (i = 1; i <= m; i++)
{
scanf("%c<%c", &a, &b);
getchar(); //除去换行符
if (!inconsistency&&!determined) //判断是否确定以及有环,如果确定了直接输出答案
{
if (graph[b - 'A'][a - 'A']==1)
{
inconsistency = true;
printf("Inconsistency found after %d relations.\n", i);
continue; //
}
if (!graph[a - 'A'][b - 'A'])
{
graph[a - 'A'][b - 'A'] = true;
indegree[b - 'A']++;
}
int res = toposort();
if (res == 0)
{
printf("Inconsistency found after %d relations.\n", i);
inconsistency = true;
}
else if (res == 1)
{
printf("Sorted sequence determined after %d relations: ", i);
for (j = 0; j < n; j++)
printf("%c", list[j] + 'A');
printf(".\n"); //这里有个句号容易丢
determined = true;
}
}
}
if (!inconsistency&&!determined)
printf("Sorted sequence cannot be determined.\n");
}
return 0;
}