1. 程式人生 > >NYOJ 496 [巡回賽-拓撲排序]

NYOJ 496 [巡回賽-拓撲排序]

content 存在 mes [0 sin 大寫 dsm n) tdi

鏈接:click here

題意:

巡回賽

時間限制:1000 ms | 內存限制:65535 KB 難度:3
描寫敘述
世界拳擊協會(WBA)是歷史最悠久的世界性拳擊組織,孕育了眾多的世界冠軍,尤其是重量級,差點兒造就了大家耳熟能詳的所有偉大的拳王。

阿裏、弗雷澤、福爾曼被稱為“70年代重量級拳壇 三巨頭”,是當之無愧的拳王,他們的得到的金腰帶都刻有 WBA 字樣。為慶賀世界拳擊協會成立 50 周年,WBA 主席門多薩邀請 N 名拳擊手進行了 M 場巡回比賽,每場比賽均可分出勝負,比賽過後組委會要對 N 名選手進行排序,對於每名拳手,必須滿足該拳手所戰勝過的對手所有排在其後才幹對該排名愜意。
現給出 M 場比賽的勝負關系,請你幫組委會決定是否可以唯一確定這種排名,使得全部的拳擊手都愜意,若能唯一確定則輸出終於排名。

輸入
第一行給出測試數據的組數 T(0<T<30),對於每組測試數據,首先依次給出N(1<=N<=26),M(0<=M<=1000)分別表示拳手數和比賽數,拳手的姓名依次為從 A開始的前 N 個大寫字母,接下 M 行給出每場比賽的比賽結果,每行由兩個大寫字母組成,兩者之間有一空格。
如 “A B”則表示在某場比賽中 A 戰勝了 B。
輸出
對於每組測試,若不存在唯一的排名序列則單行輸出“No Answer”,若存在則按排名從高至低輸出拳手的名字。
例子輸入
3
4 4
A B
A C
B C
C D
4 4
A B
A C
B D
C D
3 3
A B
B A
A C
例子輸出
ABCD
No Answer
No Answer
來源
【解題思路】:

DFS實現拓撲排序

代碼:

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using  namespace std;
const int maxn =30;
int t,n,m,V,i,j;
int g[maxn],topo[maxn],G[maxn][maxn];
bool DFS(int u)                           //DFS實現拓撲排序
{
    g[u] = -1;                             //開始訪問該頂點
    for(int v=0; v<V; v++)
        if(G[u][v])
        {
            if(g[v]<0) return false;    //c[v]=-1代表正在訪問該定點(即遞歸調用DFS(u)正在幀棧中。尚未返回)
            else if(g[v]==0&&DFS(v)==0)return false;//(c[v]==0 && DFS(v)==false即當前頂點沒有後即頂點時。
        }
    g[u]=1;                               //訪問結束
    topo[--t]=u;
    return true;
}
bool AOV_toposort()
{
    t=V;
    memset(g,0,sizeof(g));
    for(int u = 0; u < V; u++)
        if(!g[u])
            if(!DFS(u))return false;
    return true;
}
int main()
{
    //freopen("1.txt","r",stdin);
    //freopen("2.txt","w",stdout);
    int nca,i,m;
    char a[2],b[2];
    cin>>nca;
    while(nca--)
    {
        memset(G,0,sizeof(G));
        cin>>V>>m;
        for(i = 0; i < m; i++)
        {
            cin>>a>>b;
            G[(a[0]-‘A‘)][(b[0]-‘A‘)] = 1;
        }
        if(AOV_toposort())
        {
            bool flag= true;
            for(i=0; i<V-1; i++)
                if(!G[topo[i]][topo[i+1]])
                {
                    flag=false;
                    break;
                }
            if(flag)
            {
                for(i=0; i<V; i++)
                    printf("%c",topo[i]+‘A‘);
                puts("");
            }
            else
                puts("No Answer");
        }
        else
            puts("No Answer");
    }
    return 0;
}


NYOJ 496 [巡回賽-拓撲排序]