您的位置:首页 > 其它

POJ 1094 Sorting It All Out 拓扑排序

2012-08-17 01:01 260 查看
题意是 给出你一个数N,(表示 从A 开始的N个大写字母) 以及这N字母 的M个关系 ,关系是 A<B 来表示。让你判断在某一次读入数据后,能否判断出

N个字母的大小顺序,能否出现 矛盾。共三种结果 。

思路: 每次读入后,拓扑排序。。 判断能否排好序或者出现矛盾。

只要在拓扑排序上稍加改动就行。。

一 。能否排好序:每次往队列添加一个数,在抛出一个,在添加一个 ,才能是拍好序的。。。 于是 每次往队列里添加是 用个变量 num 统计填入的个数。但队列抛出操作是 num 在变成 0。

二 。会不是出现矛盾。 队列只有出现了 入度为0 的点才会出队,如果有环 ,环上的点就不会出队了 。 一开始把所有的入度为0的点入队,拓扑排序后 ,如果有剩余就 有环了。

于是用一个 outsum 统计出队的数的个数。 但outsum< n 是就形成了环

三 。 不能确定 。如果到最后一组都不能确定。就输出不能确定了。

题意隐含这一个意思 : 只要能够排序了,就不再处理后边的数据。。。。。我就在这个地方一直wa 。。。不知道这一点 。。其实这样的话程序还好些点 。。

这个题由于数据小,用邻接矩阵做就行。。用邻接链表数据处理麻烦,比如连续出现了两次 A<B 的话 就会重复 ,我没想到什么好的方法判重。。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;

int n, m ;
char input[4];
int adj[30][30];//eage
int in_deg[30];
char answer [30];//存最终的排序结果
void init(){
memset(in_deg,0,sizeof(in_deg));
memset(adj,0,sizeof(adj));
}
int topo(int  in_deg[]){
answer[0]='\0';
int indeg[30];
for(int i = 0 ;i<29;i++){
indeg[i]=in_deg[i];
}
queue <int >q;//用队列拓扑排序。。
int innum=0;//统计每次入队的数量
int outsum = 0 ;  // 统计出队的总次数
bool sigle = true; // 判断是否单进单出 也就是判断能否排序
for(int i=1; i<=n;i++){
if(indeg[i]==0){
q.push(i);
innum++;
}
}
if(innum>1){
sigle =false;
}
innum = 0 ;
int ch_idx=0;
while(!q.empty()){
int  node = q.front();
q.pop();
answer[ch_idx++]=(char)(node+'A'-1);
outsum ++;
int innum=0;
for(int i= 1;i<=n;i++){

if(adj[node][i]==1){
indeg[i]--;
if(indeg[i]==0){
q.push(i);
innum++;
}
}
}
if(innum>1){
sigle =false ;
}
}
if(outsum==n){
if(sigle)
return 2; // 可以排序
return 1;  // 不可排序
}
return 0; //矛盾
}

int main(){
while(true){
scanf("%d%d",&n,&m);
if(n==0&&m==0){
break;
}
init();
bool con = false;// 如果已经排好序 或者矛盾 后边的数据就不处理了  但要读入
int ans = -1;
answer[0]='\0';
for(int i=1;i<=m;i++){

scanf("%s",input);
if(con){
continue;
}
int  fir = input[0]-'A'+1;
int  sec = input[2]-'A'+1;
if(!adj[fir][sec]){
adj[fir][sec]=1; // 边存入邻接矩阵中
in_deg[sec]++;
}
int num = topo(in_deg);
if(num==0){
printf("Inconsistency found after %d relations.\n",i);
con =true;
}
if(num ==2){
printf("Sorted sequence determined after %d relations: ",i);
for(int j = 0 ; j< n ;j++){
printf("%c",answer[j]);
}
printf(".\n");
con =true;
}

if(i==m){
if(num == 1){
printf("Sorted sequence cannot be determined.\n");
}

}

}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: