题目地址http://acm.pku.edu.cn/JudgeOnline/problem?id=1094
每次读入一条边后,对新图作DFS找是否有环,如果有环则不用进行拓扑排序了,这种属于不能确定的情况。
否则进行拓扑排序, 因为拓扑排序的序列可能是不唯一的,拓扑排序不唯一的情况比较好判断,就是如果每次队列
中如果有多于一个点(这个点代表入度为0的点),则不唯一,如果不出现这样的点,则有唯一拓扑排序序列,最后
输出即可。
代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
const int MAXN = 30;
const int WHITE = 0;
const int BLACK = 1;
const int GRAY = 2;
int ind[MAXN];
bool map[MAXN][MAXN];
int visited[MAXN];
bool now[MAXN];
int n,m;
bool hasCircle;
bool notDet;
bool found;
char res[MAXN];
int step;
void dfs(int v)
{
visited[v] = GRAY;
for (int i=0;i<n;i++)
{
if(i==v)
{
continue;
}
if (now[i]&&visited[i]==WHITE)
{
if (map[v][i])
{
dfs(i);
if (hasCircle)
{
return;
}
}
}
else if(now[i]&&map[v][i]&&visited[i]==GRAY)
{
hasCircle = true;
return;
}
}
visited[v] = BLACK;
}
void topsort()
{
queue <int> q;
for (int i=0;i<n;i++)
{
if (now[i]&&ind[i]==0)
{
q.push(i);
}
}
int cnt = 0;
bool tMap[MAXN][MAXN];
int tind[MAXN];
memcpy(tind,ind,sizeof(ind));
memcpy(tMap,map,sizeof(map));
while (!q.empty())
{
if (q.size()>1)
{
notDet = true;
}
int cur = q.front();
q.pop();
res[cnt++] = cur+'A';
for (int i=0;i<n;i++)
{
if (now[i]&&tMap[cur][i])
{
tMap[cur][i] = false;
tind[i]--;
if (tind[i]==0)
{
q.push(i);
}
}
}
}
if (cnt==n&&!notDet)
{
found = true;
res[cnt]='\0';
}
}
int main()
{
while (scanf("%d%d",&n,&m)!=EOF&&!(n==0&&m==0))
{
memset(map,false,sizeof(map));
memset(ind,0,sizeof(ind));
memset(now,false,sizeof(now));
char inst[10];
char a,b;
hasCircle = false;
found = false;
for (int i=0;i<m;i++)
{
scanf("%s",inst);
a = inst[0];b=inst[2];
if(hasCircle||found)
{
continue;
}
map[a-'A'][b-'A'] = true;
now[a-'A'] = true;
now[b-'A'] = true;
ind[b-'A']++;
memset(visited,0,sizeof(visited));
if (!found)
{
for (int j=0;j<n;j++)
{
if (now[j]&&!visited[j])
{
dfs(j);
if (hasCircle)
{
step = i+1;
break;
}
}
}
if (!hasCircle)
{
notDet = false;
topsort();
if(found)
{
step = i+1;
}
}
}
}
if(hasCircle)
{
printf("Inconsistency found after %d relations.\n",step);
}
else if(found)
{
printf("Sorted sequence determined after %d relations: %s.\n",step,res);
}
else
{
printf("Sorted sequence cannot be determined.\n");
}
}
return 0;
}
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
const int MAXN = 30;
const int WHITE = 0;
const int BLACK = 1;
const int GRAY = 2;
int ind[MAXN];
bool map[MAXN][MAXN];
int visited[MAXN];
bool now[MAXN];
int n,m;
bool hasCircle;
bool notDet;
bool found;
char res[MAXN];
int step;
void dfs(int v)
{
visited[v] = GRAY;
for (int i=0;i<n;i++)
{
if(i==v)
{
continue;
}
if (now[i]&&visited[i]==WHITE)
{
if (map[v][i])
{
dfs(i);
if (hasCircle)
{
return;
}
}
}
else if(now[i]&&map[v][i]&&visited[i]==GRAY)
{
hasCircle = true;
return;
}
}
visited[v] = BLACK;
}
void topsort()
{
queue <int> q;
for (int i=0;i<n;i++)
{
if (now[i]&&ind[i]==0)
{
q.push(i);
}
}
int cnt = 0;
bool tMap[MAXN][MAXN];
int tind[MAXN];
memcpy(tind,ind,sizeof(ind));
memcpy(tMap,map,sizeof(map));
while (!q.empty())
{
if (q.size()>1)
{
notDet = true;
}
int cur = q.front();
q.pop();
res[cnt++] = cur+'A';
for (int i=0;i<n;i++)
{
if (now[i]&&tMap[cur][i])
{
tMap[cur][i] = false;
tind[i]--;
if (tind[i]==0)
{
q.push(i);
}
}
}
}
if (cnt==n&&!notDet)
{
found = true;
res[cnt]='\0';
}
}
int main()
{
while (scanf("%d%d",&n,&m)!=EOF&&!(n==0&&m==0))
{
memset(map,false,sizeof(map));
memset(ind,0,sizeof(ind));
memset(now,false,sizeof(now));
char inst[10];
char a,b;
hasCircle = false;
found = false;
for (int i=0;i<m;i++)
{
scanf("%s",inst);
a = inst[0];b=inst[2];
if(hasCircle||found)
{
continue;
}
map[a-'A'][b-'A'] = true;
now[a-'A'] = true;
now[b-'A'] = true;
ind[b-'A']++;
memset(visited,0,sizeof(visited));
if (!found)
{
for (int j=0;j<n;j++)
{
if (now[j]&&!visited[j])
{
dfs(j);
if (hasCircle)
{
step = i+1;
break;
}
}
}
if (!hasCircle)
{
notDet = false;
topsort();
if(found)
{
step = i+1;
}
}
}
}
if(hasCircle)
{
printf("Inconsistency found after %d relations.\n",step);
}
else if(found)
{
printf("Sorted sequence determined after %d relations: %s.\n",step,res);
}
else
{
printf("Sorted sequence cannot be determined.\n");
}
}
return 0;
}