POJ 1094 floyd+拓扑序列

这道题这真的很纠结啊~ 记得那天做完昂贵的聘礼后,直接奔向这题了,但是坑爹的题目描述硬是让我把那天写的代码重新写了一遍,其实还不止一遍,应该是两遍啊~~ 确实,我写代码还是存在着一些的问题,手速不够快,失误率太多,只能每次都按退格键。看似很快的敲击键盘,其实只是在发泄罢了。POJ服务器上不去了,搜了个对拍程序,觉得自己没什么错了,答案也是一样的。

-------------------------------------------------分割线----------------------------------------------------

郭神牛不再来了,心里很失落... 和小媛比起来我还差得远呢,她每天3题,我是3天一题,这差距~~~

-------------------------------------------------二重分割线------------------------------------------------

这题用floyd来写的,直接使用该算法看可不可达,这样形成了一个完全拓扑序列,这样怎么来处理呢?其实这个完全拓扑序列稍微思考一下就会发现规律,这个里面有一个小小的等差数列,可以简化计算,例如有26个字母,已经排列好了,那一定存在一个字母比其他25个字母都小,一个字母比其他25个字母都大。这样就是1+2+3+4+....+25,所以只要n个字母入度之和等于这样的序列的前n项和,就可以说明完全排列好了。另外判断矛盾的情况,当有入度数为0的字母时,将其出图,再把出度对应的入度字母度数切掉,再来循环,这样为零的度不为n个字母的时候就矛盾了。以上都不满足就不能确定咯~

代码还没交不知道过了没有......

#include<iostream>
#define MAXN 27
using namespace std;


int n,m;
bool map[MAXN][MAXN];
int table[MAXN];
int ans1,ans2;
int inp[MAXN];

void floyd()
{
     int i,j,k;
     for( i=1;i<=n;i++ )
          for( j=1;j<=n;j++ )
               for( k=1;k<=n;k++ )
                    if( map[i][k]&&map[k][j] )
                        map[i][j]=true;
}

char anslist[MAXN];

void makeans()
{
     memset( anslist,0,sizeof(anslist) );
     int cnt=0,i,j,k;
     bool visited[MAXN];
     memset( visited,0,sizeof(visited) );
     for( i=1;i<=n;i++ )
          for( j=1;j<=n;j++ )
          {
               if( inp[j]==0 && !visited[j] )
               {
                   visited[j]=true;
                   for( k=1;k<=n;k++ )
                        if( map[j][k] ) inp[k]--;
                   cnt++;
                   anslist[cnt]=char(j-1+'A');
               }
          }
     return ;
}

void judge( int pre )
{
     floyd();
     int i,j,k;
     int cnt=0;
     
     memset( inp,0,sizeof(inp) );
     for( i=1;i<=n;i++ )
          for( j=1;j<=n;j++ )
               if( map[i][j] ){
                   inp[j]++;cnt++;
               }
               
     if( table[n]==cnt )
     {    
          makeans();
          ans1=pre;return ;
     }
     cnt=0;
     bool visited[MAXN];
     memset( visited,0,sizeof(visited) );
     for( i=1;i<=n;i++ )
          for( j=1;j<=n;j++ )
          {
               if( inp[j]==0&&!visited[j] )
               {
                   visited[j]=true;
                   for( k=1;k<=n;k++ )
                        if( map[j][k] )
                            inp[k]--;
                   cnt++;
               }
          }
     if( cnt!=n )
         ans2=pre;
}

int main()
{
    freopen( "in.txt","r",stdin );
    freopen( "myfc.txt","w",stdout );
    int i,j,k;
    table[0]=0;
    for( i=1;i<=26;i++ )
         table[i]=table[i-1]+i-1;

    while( scanf( "%d %d",&n,&m )!=EOF )
    {
           if( n==0 && m==0 ) break;
           ans1=ans2=0;
           memset( map,0,sizeof( map) );
           int index=0;
           char a,b,c;
           for( i=1;i<=m;i++ )
           {
                scanf( "\n%c%c%c",&a,&c,&b );
                map[a-'A'+1][b-'A'+1]=true;
                if( ans1==0 && ans2==0 )
                    judge(i);
           }
           if( ans1 )
           {    
                printf( "Sorted sequence determined after %d relations: ",ans1 );
               for( k=1;k<=n;k++ )
                    printf( "%c",anslist[k] );
               printf( ".\n" ); 
           }
           else if( ans2 )
                printf( "Inconsistency found after %d relations.\n",ans2 );
           else
               printf( "Sorted sequence cannot be determined.\n" );
    }
    return 0;   
}


你可能感兴趣的:(c,算法,服务器,table)