POJ 1094解题报告

POJ 1094解题报告

这个题主要的是使用拓扑排序,相关算法随便找一本算法的书都能看到,也不难,就不罗嗦了。

我使用邻接表来保存图,并使用dm,dn分别保存每个节点(即字母)的出度和入度。

我只想强调一下需要注意的:

一、先判断是否有环路

        我就是一开始在检测到不能确定序列的时候就直接返回了,而没有判断是否有环路,结果一直WA;

二、当序列可以确定或是检测到环路的时候,忽略后边的输入。

Code:
  1. #include<iostream>  
  2. #include<fstream>  
  3. using namespace std;  
  4.   
  5. char G[26][26];  
  6. int dm[26];        //每一列的和,即每个字母的入度  
  7. int dn[26];        //每一行的和,即每个字母的出度  
  8. int m,n;  
  9. char result[27];  
  10.   
  11. int TopoSort()  
  12. {  
  13.     int index;      //起点  
  14.     int r = 0;  
  15.     int count;  
  16.     bool sorted = true;  
  17.     int dmt[26];  
  18.     int dnt[26];  
  19.     memcpy(dmt,dm,sizeof(dmt));  
  20.     memcpy(dnt,dn,sizeof(dnt));  
  21.     //找出入度为零的点  
  22.     for(int j=0;j<n;j++)  
  23.     {  
  24.         count = 0;  
  25.         for(int i=0;i<n;i++)  
  26.         {  
  27.             if(0 == dmt[i])  
  28.             {  
  29.                 index = i;  
  30.                 count++;  
  31.   
  32.             }  
  33.         }  
  34.         if(0 == count)   //发现环路  
  35.             return count;  
  36.         if(count > 1)  sorted = false;  
  37.         for(int i=0;i<dnt[index];i++)  
  38.         {  
  39.             dmt[G[index][i]-'A']--;  
  40.         }  
  41.         dmt[index] = -1;  
  42.         result[r++] = index + 'A';  
  43.     }  
  44.     result[r] = 0;  
  45.     if(sorted)  
  46.         return 1;    //序**定  
  47.     else  
  48.         return 2;    //序列不确定  
  49. }  
  50. int main()  
  51. {  
  52.     int i,j,k;  
  53.     char str[4];  
  54.     //ifstream in("data.in");  
  55.     cin>>n>>m;  
  56.     while(n&&m)  
  57.     {  
  58.         k = 0;  
  59.         int found = 0;      //可以完全确定序列  
  60.         int incons = 0;     //发现冲突,即环路  
  61.         memset(dm,0,sizeof(dm));  
  62.         memset(dn,0,sizeof(dn));  
  63.         memset(G,0,sizeof(G));  
  64.         for(i=0;i<m;i++)  
  65.         {  
  66.             cin>>str;  
  67.             if(!found && !incons)  
  68.             {  
  69.                 for(j=0;j<dn[str[0]-'A'];j++)  
  70.                 {  
  71.                     if(G[str[0]-'A'][j] == str[2])  
  72.                         break;  
  73.                 }  
  74.                 if(j == dn[str[0]-'A'])  
  75.                 {  
  76.                     G[str[0]-'A'][j] = str[2];  
  77.                     dm[str[2]-'A'] ++;  
  78.                     dn[str[0]-'A'] ++;  
  79.                 }  
  80.                 int res = TopoSort();  
  81.                 if(1 == res)  //序列已确定  
  82.                 {  
  83.                     found = i+1;  
  84.                 }  
  85.                 else if(0 == res)   //发现冲突  
  86.                 {  
  87.                     incons = i+1;  
  88.                 }  
  89.             }  
  90.         }  
  91.         if(found)  
  92.         {  
  93.             cout<<"Sorted sequence determined after "<<found<<" relations: "<<result<<"."<<endl;  
  94.         }  
  95.         else if(incons)  
  96.         {  
  97.             cout<<"Inconsistency found after "<<incons<<" relations."<<endl;  
  98.         }  
  99.         else  
  100.         {  
  101.             cout<<"Sorted sequence cannot be determined."<<endl;  
  102.         }  
  103.         cin>>n>>m;  
  104.     }  
  105.   
  106.     return 0;  
  107. }  

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值