ZOJ-1060-Sorting It All Out

这道题AC率大概是30%左右,很典型的拓扑排序。

建立二进制图map[27][27] ,第x行第y列为1代表“第x个字母<第y个字母”

找不到入度为0的字母时(入度为0:该字母只在<号左边出现,未在右边出现),该拓扑排序无解,得出矛盾。但是要注意排除map元素全部为0的情况。

一旦找到当前唯一的入度为0的字母,便记录输出在数组out[]里,去掉输出该字母的顶点和邻边,继续考察剩余图,如此重复,直到输出字母数等于n。

AC以后看了一下这道题的status,我有幸排到第一页尾,于是变本加厉改了好几个int为char,但怎么叫时间也大于00了,只能见好就收,也算是出了口前几天被1059郁闷的恶气,1059我明明对N多测试数据输出正确,但是依然WA让人简直莫明其妙,anyway,1059,1060这两道题都是跟图论有关的。

C++ 00:00.00 396K

// C++ 00:00.00 396K 
#include < stdio.h >
#include
< string .h >

char   out [ 27 ];
bool  map[ 27 ][ 27 ];
int  n,m;
//  n indicated the number of objects to sort
//  m indicates the number of relations
int  sum[ 27 ];
bool  el[ 27 ],hel[ 27 ];

void  getsum( bool  el[])
{
    
int  i,j;
    
for (i = 0 ;i <= n;i ++ )
    {
        sum[i] 
=   0 ;
    }
    
for (i = 1 ;i <= n;i ++ )
    {    
        
if (el[i])
        {
            
for (j = 1 ;j <= n;j ++ )
            {
                
if (map[i][j]  &&  el[j])
                    sum[j]
++ ;
            }
        }
    }
}

int  check() // 返回1,成功,返回0,不成,返回-1,矛盾
{
    
int  i,countdel = 0 ,pos,count,tot = n;
    
int  flag  =   1 ;
    
for (i = 0 ;i <= n;i ++ )
    {
        el[i] 
=   1 ;
        hel[i] 
=   1 ;
        
out [i]  =   0 ;
    }        
    
while (countdel < n)    
    {        
        count
= 0 ;
        getsum(el);
        
for (i = 1 ;i <= n;i ++ )
        {    
            
if ( 0 == sum[i]  &&  el[i])
            {
                count
++ ;
                hel[i] 
=   0 ;
                pos 
=  i;
            }    
        }        
        
if ( 1 == count)
        {
            countdel
++ ;
            el[pos] 
=   0 ;
            tot
-- ;
            
out [countdel]  =  pos  +   64 ;
        }
        
else   if ( 0 == count)
        {
            flag 
=   - 1 ;
            
return  flag;
        }
        
else   if (count > 1 )
        {
            
if (count == tot)
            {
                flag 
=   0 ;
                
return  flag;
            }
            getsum(hel);
            
int  key = 0 ;
            
for (i = 1 ;i <= n;i ++ )
            {    
                
if ( 0 == sum[i]  &&  hel[i])
                {
                    key
++ ;
                }    
            }    
            
if ( 0 == key)
            {
                flag 
=   - 1 ;
                
return  flag;
            }
            
else
            {
                flag 
=   0 ;
                
return  flag;
            }
        }
    }    
    
return  flag;
}

void  solve()
{
    
int  i,j,temp;
    
char  re[ 3 ];
    
for (i = 1 ;i <= m;i ++ )
    {
        scanf(
" %s " , re);
        map[re[
0 ] - 64 ][re[ 2 ] - 64 =   1 ;
        temp 
=  check();
        
if ( 1 == temp)
        {
            printf(
" Sorted sequence determined after %d relations:  " , i);
            
for (j = 1 ;j <= n;j ++ )
                printf(
" %c " out [j]);
            printf(
" ./n " );
            
            
for (j = i + 1 ;j <= m;j ++ )
                scanf(
" %s " , re);        
            
return ;
        }
        
else   if ( - 1 == temp)
        {
            printf(
" Inconsistency found after %d relations./n " , i);
            
            
for (j = i + 1 ;j <= m;j ++ )
                scanf(
" %s " , re);    
            
return ;
        }        
    }    
    printf(
" Sorted sequence cannot be determined./n " , i);
}

int  main()
{
//     freopen("01060.txt","r",stdin);
     while (scanf( " %d %d " & n,  & m) != EOF  &&  n > 0   &&  m > 0 )
    {        
        memset(map,
false , sizeof (map));
        solve();
    }
//     fclose(stdin);
     return   0 ;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值