Poj 1094 Sorting It All Out——拓撲排序

題目鏈接:

http://poj.org/problem?id=1094


題目大意:

這個題目的難點就在於題目意思的理解。

有n個大寫字母,並且告訴這n個大寫字母的大小關係,要你對這n個大寫字母進行排序。


解題思路:

但是,這個題目並不是等所有的輸入結束之後判斷,而是一邊輸入一邊進行判斷。

每次輸入一組字母的關係之後,我們就需要更新原來的圖。


如果原來的圖已經能夠確定一個排序或者已經能夠確定不能排序,那麼就不用進行排序了。

如果原來的圖不能確定一個排序,那麼進行一次拓撲排序。


拓撲排序之後,如果出現了環,則說明找不到這樣的一個拓撲排序。

如果這個時候已經可以將所有的字母排序了,那麼餘下的那些字母關係我們不需要再理會。

但是最後一定要記得把所有的輸入都讀進去。


源代碼:

#include<stdio.h>
#include<stdlib.h>
#include<string>

#include<string.h>

#include<math.h>
#include<cmath>
#include<vector>
#include<map>
#include<iostream>
#include<algorithm>
using namespace std;
int s[27][27];
int key[27];
int d[27];     //記錄下每個點的度數
int d1[27];    //暫時存儲每個點的度數
int flag,n,m,ans;
void top_order()        //拓撲排序
{
    int i,j,k,cnt,cc;
    cc=0;
    for(i=1;i<=n;i++)
    {
        d1[i]=d[i];
//        printf("%d\n",d1[i]);
    }
    for(i=1;i<=n;i++)   //尋找第1個點
    {
        cnt=0;
        for(j=1;j<=n;j++)
        {
            if(d1[j]==0)
            {
                cnt++;
                k=j;
            }
        }
        if(cnt==0)              //沒有解的情況
        {
            flag=1;
            break;
        }
        if(cnt==1)  cc++;
        d1[k]=-1;
        key[i]=k;
        for(j=1;j<=n;j++)
            if(s[k][j])
                d1[j]--;
    }
    if(cc==n)   flag=2;
    return;
}
int main()
{
    freopen("in.txt","r",stdin);
    int a,b,i,j;
    char x,y;
    while(scanf("%d%d",&n,&m)==2 && n+m)
    {
        getchar();
        memset(s,0,sizeof(s));
        memset(d,0,sizeof(d));
        memset(key,0,sizeof(key));
        ans=0;
        flag=0;         //初始化爲2,是因爲沒有輸入的時候是不能確定排序的
        for(i=1;i<=m;i++)          //每輸入一組解就對該圖進行一次拓撲排序,如果出現環或者排序已經出來了,則可以輸出最後結果
        {
            scanf("%c<%c",&x,&y);
            a=x-64;
            b=y-64;
            getchar();
            if(a==b)        //去掉自環的情況
                flag=1;
            if(!s[a][b])    //可能出現重邊
            {
                s[a][b]=1;
                d[b]++;
            }
            if(flag==0)         //前一狀態的圖還不能確定一個排序,進行進一步的排序
                top_order();
            if(flag==1)
            {
                if(!ans)    ans=i;
                continue;       //出現了環,不往下做,但是數據必須輸入完
            }
            if(flag==2)
            {
                if(!ans)    ans=i;
                continue;       //已經能得到一個唯一的拓撲排序了,不往下做了
            }
        }


        if(flag==1)     //出現了環的情況
        {
            printf("Inconsistency found after %d relations.\n",ans);
        }
        else if(flag==0)    //有多種解的情況
        {
            printf("Sorted sequence cannot be determined.\n");
        }
        else if(flag==2)    //只有唯一解的情況
        {
            printf("Sorted sequence determined after %d relations: ",ans);
            for(i=1;i<=n;i++)
                printf("%c",key[i]+64);
            printf(".\n");
        }
    }
    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章