• 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]='';
    }
    


  • 相关阅读:
    随笔 Frida
    [转]某种传染病第一天只有一个患者,前五天为潜伏期,不发作也不会传染人 第6天开始发作,从发作到治愈需要5天时间,期间每天传染3个人 求第N天共有多少患者 Frida
    sql 将具有相同ID的多条记录组合成一条记录 Frida
    【转】小谈C#.NET下的爬虫(蜘蛛)技术 Frida
    ECMAScript基础1 Frida
    显示隐藏层 jquery Frida
    SQL语句备份和还原数据库
    Hello!Blog~
    23个MySQL常用查询语句
    SQL Server 2008压缩数据库日志文件
  • 原文地址:https://www.cnblogs.com/dyllove98/p/3162972.html
Copyright © 2020-2023  润新知