zoukankan      html  css  js  c++  java
  • poj 1094 Sorting It All Out (拓扑排序)

         只是利用拓扑排序来计算!每加一个表达式就计算出他的拓扑排序:

        1,不存在拓扑排序,就是表明这些表达式存在矛盾

        2,如果存在唯一的拓扑排序,就可以输出结果

        3,如果不存在唯一的排序,即存在入度相同的点,此时表示不能确定排序关系或者存在结果矛盾(所以在不能确定排序的时候,还要判断是不是存在环,从而确定是不是存在拓扑排序)


    #include <iostream>
    //#include <fstream>
    using namespace std;
    #define MAX 30
    /*340K	16MS*/ 
    //var
    int n;
    int a[MAX][MAX];
    bool flag1,flag2; //flag1代表发现矛盾,flag2代表出现想要的结果
    char s[MAX]; 
    //fstream fin;
    
    //function
    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));
            flag1=flag2=false;
            int count=0;
            
            char b1,b2;
            for(int i=0;i<m;i++)
            {
                cin>>b1>>b2>>b2;
                if(flag1||flag2)  continue;
                if(a[b1-'A'][b2-'A']==0)
                {
                    a[b1-'A'][b2-'A']=1;
                    //计算出拓扑排序
                    toposort(); 
                } 
                ++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;
    }
    
    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]++;
         
         for(int i=0;i<n;i++)
         { 
                 //入度为0的点 
                 int t=-1;
                 for(int j=0;j<n;j++)
                 {
                         if(ind[j]==0&&t==-1)
                              t=j; 
                         else if(ind[j]==0&&t!=-1)
                         {   
                             //当存在多个入度为0的点时还是要记得去判断是不是存在环 
                              for(int kk=0;kk<n;kk++)
                                 for(int ii=0;ii<n;ii++)
                                    for(int jj=0;jj<n;jj++)
                                       if(a[ii][jj]||a[ii][kk]&&a[kk][jj])
                                          a[ii][jj]=1;
                                       
                              for(int ii=0;ii<n;ii++)
                                 if(a[ii][ii])
                                    flag1=true;
                                    
                              return;}   //代表有多个入度为0的点,即不能够进行排序 
                 }
                 if(t==-1)
                     {flag1=true;return;}        //代表存在着环
                   
                 //相应的边对应的度减一
                 for(int j=0;j<n;j++)
                      if(a[t][j]==1)
                           ind[j]--; 
                 
                 ind[t]--;    
                 s[i]='A'+t;
         } 
         flag2=true;
         s[n]='';
    }
    


  • 相关阅读:
    VS2008编写MFC程序--使用opencv2.4()
    November 02nd, 2017 Week 44th Thursday
    November 01st, 2017 Week 44th Wednesday
    October 31st, 2017 Week 44th Tuesday
    October 30th, 2017 Week 44th Monday
    October 29th, 2017 Week 44th Sunday
    October 28th, 2017 Week 43rd Saturday
    October 27th, 2017 Week 43rd Friday
    October 26th, 2017 Week 43rd Thursday
    October 25th, 2017 Week 43rd Wednesday
  • 原文地址:https://www.cnblogs.com/dyllove98/p/3162972.html
Copyright © 2011-2022 走看看