现在的位置: 首页 > 综合 > 正文

POJ 1094 Sorting It All Out 拓扑排序

2013年02月03日 ⁄ 综合 ⁄ 共 1912字 ⁄ 字号 评论关闭

题意是  给出你一个数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;
}

抱歉!评论已关闭.