この質問は、本質的にフロイド推移閉包を求めている、いわゆる推移閉包があり、このように、つまり、転送中に閉鎖要素間の関係のいくつかの種類を持っている非常にシンプル。
この質問のデータ範囲が小さいので、我々は、隣接行列を開始することができ、フロイド[I] [J]は、I> jで表します。私たちが判断した場合、非常に簡単です、フロイド[I] [J] ==フロイド[J] [i]を== 1、それは矛盾である、フロイド[I] [J] == 0とフロイド[J] [I] == 0は、大小関係は、Iを記述することができ、jは決定できません。この2後で知って、この質問は難しいことではありません。最初に、従来は各添加、一方のエッジの後に推移閉包を求め、不等式T基を列挙体に。この判断の矛盾、ソート成功、列挙完成のトンセットした後、あなたはソートできるかどうかを判断することができます。
次のように参照コードは次のとおりです。
書式#include <iostreamの> の#include <CStringの> の#include <アルゴリズム> std名前空間を使用しました。 構造体ノード { int型nodee、NUM。 } F [10001]。 INTフロイド[127] [127]、N、M、[100001] A1、B1 [100001]、C1 [100001]。 A、B、Cのchar型、 BOOL CMP(ノードA、ノードB) { 戻りa.num <b.num。 } int型のmain() { BOOLフラグ。 int型PD = 12345678; 一方、(1) { CIN >> N >> M。 (!N &&メートル)であれば、戻り0; フラグ= 0。 PD = 0; memset(フロイド、0、はsizeof(フロイド))。 用(INT T = 1; T <= M; T ++) { CIN >> A >> int型、X = A-'A '+ 1、Y = C-' F [X] .nodee = xであり、f [x]は.num = 0。 F [Y] .num = 0; [Y] .nodee = Y F。 (フラグ)続ける場合。 IF(B == '<')フロイド[X] [Y] = 1。 他フロイド[Y] [X] = 1。 用(int型K = 1; kは<= N; ++ K) { ため(iは++; iがn = <I = 1 INT) { ため(int型のJ = 1; J <= nであり、j ++) { フロイド[I] [ J] | =フロイド[i]の[K]&フロイド[k]は[J]。 } } } のために(iは++; iがn = <I = 1 INT) { ため(int型J = I + 1、J <= nであり、j ++) { IF(フロイド[I] [J] &&フロイド[J] [I ]) { フラグ= 1。 もし(フラグ)ブレーク。 } 裁判所未満<<「矛盾後に発見されました」 ブレーク; } } (フラグ)が続けば、 int型FSS = 1; 以下のために(INT i = 1; iは++; iが= N <) { IF(PDを= 0 && PD = 12345678!) { FSS = 0。 ブレーク; } のための(int型J = I + 1、J <= nであり、j ++) { IF(フロイド[I] [J] &&フロイド[J] [I]!) { FSS = 0。 もし(T Mを==) { COUTは<< "ソート順を決定することができない。" << ENDL。 フラグ= 1。 ブレーク; } } } 場合(フラグ)ブレーク。 } (フラグ)が続く場合、 IF(FSS == 1) { PD = T。 以下のために(INT i = 1; iが<= N; iは++します) { (INT J = 1; J <= N; J ++)用 { IF(!フロイド[I] [J] && I = J)F [J] .num ++。 } } ソート(F + 1、F + 1 + N、CMP)。 coutの<< << PD <<「の関係: 『』後に決定されるソート順」。 以下のために(INT i = 1; iが<= N; iは++)COUT <<チャー(F [i]が.nodee + 'A'-1)。 ""はcout << <<てendl; フラグ= 1。 } } } }