効果の対象に
N- $ $ノードを有し、$ M $は、これはオイラー図に存在するかどうかを求めて、図は、($ 1 \当量のN \当量200 $、$ 1 \当量M \当量$ 1000)を混合するエッジ。
問題の解決策
混合した側面があるので、私たちは最初に方向を調整する、ランダムに配向無向エッジを与えなければなりません。
ランダムに配向した後、我々は有向グラフを取得します。
我々は、[i]は$ $ INDの各ノードに記録され、$ OUTD度[I]オイラー経路の性質に応じて$は、得ることができ、場合$ IND [I] + OUTD [i]は$が奇数でありますオイラー特定の方法は存在しません。
、プロセスの建設側の元のエッジを有するように変更することができないので、我々は無視することができ、ランダムに、容量$ 1のみ$(各エッジに設定されている有向エッジと側に向け読み取る必要がないという理由だけであなたは)一度行くことができます。
各$ IND [I] \当量OUTDため[i]は$ノード$ Iの$、我々は、[i]は、$ I $も有向エッジにソース$ S $から$ \ FRAC {OUTDの容量を有します - IND [I]} {2} $、$ INDための[I]> OUTD [i]は$ノード$ Iの$、$ Iから$ $さt $も有向エッジ、$ \ FRACの容量{にIND [I] - OUTD [I]} {2} $。これら双方の意味は、変更する必要があり、エッジノード$ Iの$に接続されたエッジの数です。
明らかに、我々は$の最大流量、最後の判断と$ S $ $ sのかどうか、完全な流れに接続$さt $のエッジからを実行し始めました。
書式#include <iostreamの> の#include <cstdioを> する#include <CStringの> の#include <キュー> #define MAX_N(200 + 5) の#define MAX_M(+ 5 1000) 使用して 名前空間はstdを、 構造体のエッジ { int型へ。 int型の重量; int型の次; }。 int型T; INTのN、M。 int型S、T; INT H [MAX_N]すべて= 1 。 エッジe [MAX_N + MAX_M << 1 ]。 int型IND [MAX_N]を、OUTD [MAX_N]。 int型DEP [MAX_N]。 int型CUR [MAX_N]。 キュー < 整数 > Q; int型maxflow; インライン無効 AddEdge(int型のu、int型 V、int型ワット) { E [ ++ TOT] .TO = V? E [TOT] .weight = W。 E [TOT] .next =をH [U]。 H [U] = TOT。 返します。 }。 BOOL BFS() { memset(DEP、0x7Fを、はsizeof DEP)。 memcpy(CUR、H、はsizeof CUR)。 q.push(S); DEP [S] = 0 ; int型U、V、W; しばらく(!q.empty()) { U = q.front()。 q.pop(); 用(int型 ; I; I = [U] I = HをE [I] .next) { V = E [i]の.TO? W = E [I] .weight。 もし(DEP [V]> DEP [U] + 1 && W) { [V] DEP = DEPを[U] + 1 。 q.push(V); } } } 返す!DEP [T] = 0x7f7f7f7fを。 } int型 DFS(int型のu、int型の流れ) { 場合(Uは== t)を { maxflow + = 流量; リターンフロー; } int型V、W; int型 TMP、合計= 0 ; 用(INT I = CUR [U]は、iが流れ&&; I = E [I] .next) { cur変換[U] = I。 V = E [i]の.TO? W = E [I] .weight。 もし(DEP [V] == DEP [U] + 1 && W &&(TMP = DFS(V、)))W分(フロー) { E [i]は.weight - = TMP。 E [I ^ 1 ] .weight + = TMP。 合計 + = TMP; 流れ - = TMP; } } 戻り値の合計。 } 無効Dinicを() { 一方、(BFS())DFS(S、0x7f7f7f7f )。 返します。 } int型のmain() { scanf関数(" %のD "、&T)。 しばらく(T-- ) { memsetの(H、0、はsizeofのH)。 memset(IND、0、はsizeof IND)。 memset(OUTD、0、はsizeof OUTD)。= 1 。 maxflow = 0 ; scanf関数(" %d個の%のD "、&N、&M)。 S = 0 。 T = N + 1 。 int型U、V、D; 以下のために(int型 I = 1 ; I <= M; ++ I) { scanf関数(" %D%D%D "、およびuは、&V、&D)。 ++ OUTD [U]。 ++ IND [V]。 もし(!D) { AddEdge(U、V、1 )。 AddEdge(V、U、0 ); } } BOOL isEuler = 真; 以下のために(int型 i = 1 ; iは= N <; ++ I) { もし(IND [I] + OUTD [I]&1 ) { isEuler = 偽; 破ります; } } もし(!isEuler) { printf(" 不可能\ nを" ); 続け; } int型 TMP = TOT; 以下のために(int型 i = 1 ; iは= N <; ++ I) { もし(IND [i]が<= OUTD [i])と { AddEdge(S、I、OUTD [I] - IND [I] >> 1 )。 AddEdge(I、S、0 ); } 他 { AddEdge(I、T、IND [I] - OUTD [I] >> 1 )。 AddEdge(T、I、0 ); } } Dinic(); 用(int型 iはTMP + = 1 ; I <= TOT; I + = 2 ) { もし(E [i]の.weight) { isEuler = 偽; 破ります; } } もし(!isEuler)のprintf(" 不可能\ nを" ); 他のprintf(" 可能\ nを" ); } リターン 0 ; }