题目连接:http://acm.pku.edu.cn/JudgeOnline/problem?id=1094
1,用arc[MAX][MAX]存储图,但是有效结点可能少于MAX而且还可能不连续,所以用in[MAX]这个辅助数组标示arc中的哪些结点是有效的
2,这道题的输出结果有三种即在若干步骤后能排序、在若干步骤后判定出有环、在所有步骤后判定不能排序。分清三者的逻辑关系是非常重要的,开始一直错原因就是没有分清逻辑关系。删去某零度顶点后有多于一个零度顶点出现,这种情况是不能确定的情况,但是不能就此结束还要继续看完以判断图中是否有环,我就一直错到这里了。
#include <iostream>
#include <queue>
using namespace std;
#define MAX 26
struct Graph
{
bool arc[MAX][MAX];
int v_num;
int c_num;
bool in[MAX];
int indeg[MAX];
};
int t_sort(Graph& g,queue<int>& q)
{
int i,j;
for(i = 0;i < g.v_num;++i)
g.indeg[i] = 0;
for(i = 0;i < g.v_num;++i)
{
for(j = 0;j < g.v_num;++j)
if(g.arc[i][j])
++g.indeg[j];
}
queue<int> qq;
for(i = 0;i < g.v_num;++i)
{
if(g.in[i] && g.indeg[i] == 0)
qq.push(i);
}
int cur;
bool sure = true;
while(!qq.empty())
{
if(qq.size() > 1)
//return 0;不能直接返回0表示不确定,还要继续看完看能不能发现环
sure = false;
cur = qq.front();
qq.pop();
q.push(cur);
for(i = 0;i < g.v_num;++i)
{
if(g.in[i] && g.arc[cur][i])
{
--g.indeg[i];
if(g.indeg[i] == 0)
qq.push(i);
}
}
}
if(q.size() < g.c_num)//先判断是否有环
return -1;
else if(sure && q.size() == g.v_num)//无环时再看是否已经能排好序,能排好序有两种情况即多种拓扑排序中的一种或者仅确的
//一种这里必须是后者才行,否则返回不确定
return 1;
else
return 0;
}
int main()
{
freopen("in.txt","r",stdin);
int i,j,m;
char a,b;
Graph g;
bool ok;
while(cin >> g.v_num >> m)
{
if(g.v_num == 0 && m == 0)
break;
memset(g.arc,0,sizeof(g.arc));
memset(g.in,0,sizeof(g.in));
g.c_num = 0;
ok = false;
for(i = 0;i < m;++i)
{
cin >> a >> b >> b;
if(ok)
continue;
if(!g.in[a-'A'])
{
g.in[a-'A'] = true;
++g.c_num;
}
if(!g.in[b-'A'])
{
g.in[b-'A'] = true;
++g.c_num;
}
g.arc[a-'A'][b-'A'] = true;
queue<int> q;
j = t_sort(g,q);
if(j == -1)
{
printf("Inconsistency found after %d relations./n",i+1);
ok = true;
}
else if(j == 1)
{
printf("Sorted sequence determined after %d relations: ",i+1);
while(!q.empty())
{
cout << char('A' + q.front());
q.pop();
}
cout << "./n";
ok = true;
}
}
if(!ok)
printf("Sorted sequence cannot be determined./n");
}
return 0;
}