問題の意味:
n個の点を考えると、各点は重み値[I]を、持っている場合、[U]および[Vそれは(u、v)があっても、エッジ、シークの間であってもよいです!最後に、図最小リング(数ドットによって形成される環)
溶液:
論理演算は&バイナリ下で操作され、対象の各重み値[i]は、次のアップ、すなわち、64ビットのバイナリ1018の最大範囲です。
64 1 2より大きい出現特定の数が存在する場合、最小の環が3(位置ループ)であることは明らかです。
別の方法は、数0から128以下である最悪の場合、数nが与えられ、中には、答えは3(128なければならない数は、各64ビットは、0でない場合ためビットの数は限り数が何気なく0ないので、)リング3を構成する、2つの以上のビットが存在することになる、2で
あれば、我々は数ライン130上の0の数未満である場合を考慮していないとして、nは、この時間は非常に小さく、最小探索DFSまたは環Flyodのために使用することができます。
書式#include <iostreamの> の#include < 文字列 > の#include < 文字列の.h> の#include <アルゴリズム> 書式#include <math.h>の の#define LL長い長い の#define 0x3f3f3f3f MX 使って 名前空間はstdを、 LL方法[ 250 ] [ 250 ]、DIS [ 250 ] [ 250 ]、NUM [ 250 ]。 LL N、M、ANS。 無効INITを() { ため(int型 i = 1 ; iが++; iが<= N ) { ため(INTJ = 1 ; J <= nであり、j ++ ) { もし!(I = J && NUM [I]&NUM [J]) 方法[I] [J] = DIS [I] [J] = 1 。 他の 方法[I] [J] = DIS [i]は[J] = MX; } } } ボイドフロイド() { ANS = MX。 用(int型のk = 1 ; kは<= N; ++ k個) { ため(int型 i = 1 ; iはK <; iは++ ) { ための(int型 J = I + 1; J <K、J ++ ) ANS =分(ANS、DIS [I] [J] +方法[I] [K] +方法[K] [J])。// 接成环 } ため(int型 i = 1 ; iが= N <; I ++)// 求最短路 ため(INT J = 1 ; J <= N; J ++ ) DIS [I] [J] =分(DIS [I]、[J]、DIS [I] [K] + DIS [K] [J])。 } } int型のmain() { ながら(〜のscanf(" %のLLD "、&N)) { LLのCNT = 0 。 以下のための(int型 i = 1 ; iが<= N; iが++ ) { scanf関数(" %のLLDを"、&NUM [I])。 もし(NUM [i])と CNT ++ 。 } であれば(CNT> 130 ) のprintf(" 3 \ n " ); 他 { INIT()。 フロイド(); もし(ANS == MX) のprintf(" -1 \ nを" ); 他 のprintf("%LLD \ n " 、ANS); } } 戻り 0 ; }