poj 1094 Sorting It All Out(图论)

http://poj.org/problem?id=1094

这一题,看了个大牛的解题报告,思路变得非常的清晰:

1,先利用floyd_warshall算法求出图的传递闭包

2,再判断是不是存在唯一的拓扑排序,利用出度和入度是不是相加为n-1

3,利用拓扑排序求出当前的图形的唯一的拓扑排序


一开始我的思路跟上述的差不多,但是没有利用floyd_warshall算法求出传递闭包,准备着利用拓扑排序求出是不是存在着有环回路,我觉得我的这个思路也是可以的。等一下我会将我的这个思路给写成程序。在我的百度云中有这个程序的测试数据(来自poj)

http://pan.baidu.com/disk/home#dir/path=%2Facm%2F%E5%8C%97%E5%A4%A7acm%2F1094  


 

#include <iostream>

//#include <fstream>

using namespace std;

#define MAX 30

/*396K	16MS*/

//var

int a[MAX][MAX];

int n;

int flag1,flag2;  //falg1代表的是当前有环的错误,即存在错误的排序 

char s[MAX];     //存放最后的结果 

//fstream fin;

//function

bool transition();

bool judge();

void toposort();



//main函数 

int main()

{

    //fin.open("1094.txt",ios::in);

    int m;

    while(cin>>n>>m)

    {

         if(n==0&&m==0)  break;

         memset(a,0,sizeof(a));

         int count=1;

         flag1=flag2=false;

         for(int i=0;i<m;i++)

         {

            char b1,b2;

            cin>>b1>>b2>>b2;

            if(flag1||flag2) continue; 

            if(a[b1-'A'][b2-'A']==0)

            {

                a[b1-'A'][b2-'A']=1;

                //求传递闭包,判断是不是有环,这样就知道是不是存在着错误的答案 

                if(!transition()){flag1=true;continue;}

                //判断是不是存在着唯一的拓扑排序 

                else if(judge())

                {

                     toposort();

                     flag2=true;

                     continue;

                } 

            }

            ++count;

         }

         

         if(flag1)

            cout<<"Inconsistency found after "<<count<<" relations."<<endl;

         else if(flag2)

            cout<<"Sorted sequence determined after "<<count<<" relations: "<<s<<"."<<endl;

         else

            cout<<"Sorted sequence cannot be determined."<<endl;

    }

    system("pause");

    return 0;

}



//求传递闭包

bool  transition()

{

      for(int k=0;k<n;k++)

        for(int i=0;i<n;i++)

           for(int j=0;j<n;j++)

              if(a[i][j]==1||a[i][k]==1&&a[k][j]==1)

                 a[i][j]=1;

                 

      for(int i=0;i<n;i++)

         if(a[i][i]==1)

           return false;

      return  true;

}



//计算是不是存在着唯一的拓扑排序

bool judge()

{

     int *ind=new int[n];

     int *outd=new int[n];

     memset(ind,0,sizeof(int)*n);

     memset(outd,0,sizeof(int)*n);

     for(int i=0;i<n;i++)

     {

             for(int j=0;j<n;j++)

             {

                     if(a[i][j])

                     {

                         ind[j]++;

                         outd[i]++;

                     }

             }

     }

    

     for(int i=0;i<n;i++)

       if(ind[i]+outd[i]<n-1)

          return false;

       return true;

} 



//拓扑排序的实现 

void toposort()

{

     //按照入度来进行计算

     int *ind=new int[n];

     memset(ind,0,sizeof(int)*n);

     for(int i=0;i<n;i++)

     {

             for(int j=0;j<n;j++)

                   if(a[i][j]==1)

                      ind[j]++;

     } 

     

     //求出入度后计算出当前的的拓扑排序的结果

     int t=n;

     for(int i=0;i<n;i++)

     {

             int j;

             for(j=0;j<n;j++) 

                 if(ind[j]==0)

                 { ind[j]--; s[i]=j+'A'; break;}

             int t=j;

             for(j=0;j<n;j++)

                 if(a[t][j]==1)

                     ind[j]--;

     } 

    

     s[n]='\0';

}


 

 

你可能感兴趣的:(sort)