POJ1094拓扑排序
题目分析
http://poj.org/problem?id=1094
本题给出AOV活动网络的一个拓扑排序问题,要求给出:唯一的一个拓扑序列 || 拓扑序列不唯一 || 不存在拓扑序列,并指出使用了所有关系中的前几个得到了以上三个结论中的一个
拓扑排序的基本思想,循环执行以下两步直到不能执行为止:
(1) 选择一个入度为0的顶点并输出之;
(2) 从网中删除此顶点及所有出边。
拓扑序列不存在:循环完成后网络中仍然有顶点
拓扑序列唯一:循环过程中可删除的顶点一直有且只有一个
拓扑序列不唯一:剩下的情况
数据结构方面,假如使用邻接表的形式,以边终点来组织的话,容易找入度为零的点,但是不容易删这个点上的出边;以边起点来组织的话,容易删除这个点上的出边,但是不容易找入度为零的点。因此直接采取邻接矩阵,可以折中的解决这两个问题,使用一个数组来记录每个点是否在网络中
字符串输入输出方面,慎用cin/cout,建议使用C语言库函数getchar(),gets()等
ver 1.0
题目比较绕,第一次遇到了gets()函数的问题,解决后仍然wa了,运行以下测试数据发现了一组错误
http://poj.org/showmessage?message_id=133905
http://poj.org/showmessage?message_id=90819
问题出在写的时候偷了下懒,在处理过程中只要有超过一个可以删除的点,立刻就终止循环并认为拓扑序列不唯一,忽视了此时有可能是拓扑序列不存在
代码没有参考其他人的博客,完全自写,比较长,用了很多bool flag,感觉很绕,并不是很好
#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std;
const int MAXN= 30;
int mat[MAXN][MAXN];
int mat1[MAXN][MAXN];
int vis[MAXN];
queue<int> q;
bool fff = false;
int topSort(int n){
for(int i = 0;i < MAXN;i++)
for(int j = 0;j < MAXN;j++)
mat1[i][j] = mat[i][j];
while(!q.empty()) q.pop();
for(int i = 0;i < n;i++) vis[i] = 1;
bool flag = false;
for(int i = 0;i < MAXN;i++){
if(vis[i]){
flag = true;
break;
}
flag = false;
}
while(true){
if(fff)
for(int i = 0;i < n;i++){
for(int j = 0;j < n;j++)
printf("%d ",mat1[i][j]);
printf("\n");
}
int cnt = 0,temp = -1;
for(int i = 0;i < MAXN;i++){
if(vis[i]!=0){
bool f = false;
for(int j = 0;j < MAXN;j++){
if(mat1[j][i] != 0){
f = true;
break;
}
}
if(!f){
cnt++;
temp = i;
}
}
}
if(cnt == 1){
q.push(temp);
vis[temp] = 0;
for(int i = 0;i < MAXN;i++){
if(vis[i]){
flag = true;
break;
}
flag = false;
}
for(int i = 0;i < MAXN;i++){
mat1[temp][i] = 0;
}
if(!flag){
return 1;
}
}
else if(cnt == 0 && flag) return 0;
else if(cnt > 1) return 2;
}
}
int main(){
while(true){
int m,n;
bool flag = false;
scanf("%d%d",&n,&m);
if(m==0&&n==0) break;
memset(mat,0,sizeof(mat));
memset(vis,0,sizeof(vis));
while(!q.empty()) q.pop();
for(int i = 0;i < n;i++) vis[i] = 1;
getchar();//回车
for(int i = 0;i < m;i++){
char temp[5];//gets()会在末尾加上\0不推荐使用了
gets(temp);
mat[temp[0]-'A'][temp[2]-'A'] = 1;
if(i == 47) fff = true;else fff = false;
int tmp = topSort(n);
if(tmp == 1 && !flag){
printf("Sorted sequence determined after %d relations: ",i+1);
while(!q.empty()){
printf("%c",char(q.front()+'A'));
q.pop();
}
printf(".\n");
flag = true;
}
else if(tmp == 0 && !flag){
printf("Inconsistency found after %d relations.\n",i+1);
flag = true;
}
}
if(!flag) printf("Sorted sequence cannot be determined.\n");
}
return 0;
}
ver 2.0
#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std;
const int MAXN= 30;
int mat[MAXN][MAXN];
int mat1[MAXN][MAXN];
int vis[MAXN];
queue<int> q;
int topSort(int n){
for(int i = 0;i < MAXN;i++)
for(int j = 0;j < MAXN;j++)
mat1[i][j] = mat[i][j];
while(!q.empty()) q.pop();
for(int i = 0;i < n;i++) vis[i] = 1;
bool flag = false;
bool fl = false;
for(int i = 0;i < MAXN;i++){
if(vis[i]){
flag = true;
break;
}
flag = false;
}
for(int g = 0;g < n;g++){
int cnt = 0,temp = -1;
for(int i = 0;i < MAXN;i++){
if(vis[i]!=0){
bool f = false;
for(int j = 0;j < MAXN;j++){
if(mat1[j][i] != 0){
f = true;
break;
}
}
if(!f){
cnt++;
temp = i;
}
}
}
if(cnt == 1){
q.push(temp);
vis[temp] = 0;
for(int i = 0;i < MAXN;i++){
if(vis[i]){
flag = true;
break;
}
flag = false;
}
for(int i = 0;i < MAXN;i++){
mat1[temp][i] = 0;
}
if(!flag && !fl){
return 1;
}
}
else if(cnt == 0 && flag) return 0;
else if(cnt > 1){
fl = true;
vis[temp] = 0;
for(int i = 0;i < MAXN;i++){
if(vis[i]){
flag = true;
break;
}
flag = false;
}
for(int i = 0;i < MAXN;i++){
mat1[temp][i] = 0;
}
}
}
return 2;
}
int main(){
while(true){
int m,n;
bool flag = false;
scanf("%d%d",&n,&m);
if(m==0&&n==0) break;
memset(mat,0,sizeof(mat));
memset(vis,0,sizeof(vis));
while(!q.empty()) q.pop();
for(int i = 0;i < n;i++) vis[i] = 1;
getchar();//回车
for(int i = 0;i < m;i++){
char temp[5];//gets()会在末尾加上\0不推荐使用了
gets(temp);
mat[temp[0]-'A'][temp[2]-'A'] = 1;
int tmp = topSort(n);
if(tmp == 1 && !flag){
printf("Sorted sequence determined after %d relations: ",i+1);
while(!q.empty()){
printf("%c",char(q.front()+'A'));
q.pop();
}
printf(".\n");
flag = true;
}
else if(tmp == 0 && !flag){
printf("Inconsistency found after %d relations.\n",i+1);
flag = true;
}
}
if(!flag) printf("Sorted sequence cannot be determined.\n");
}
return 0;
}
532K 16MS