@codeforces - Bitlandでアクセルとマーストン@ 781D


@説明@

:以下の方法によりシーケンスを生成する
唯一の「P」(1)初期。
(2)「B」に現在の文字列sを「P」、「B」は、Sを得るために「P」となる」、S'の新たなシーケンスとの接触後に得られました。
P、PB、PBBP、PBBPBPPBの文字列を与えるために、最初のいくつかの手順を生成する......

有向グラフ、文字「P」または「B」の各エッジを考えます。点1から開始する最長パス(すなわち、歩行S [1]における第一工程、第二工程テイクS [2]、...)最長の可能な長さの上記配列を見つけることができます。
> 10 ^ 18の長場合、-1が出力されます。

入力
二つの整数の最初の行のN、M(1≤N≤ 500、0≤M≤2N ^ 2)、 点とエッジの数を表します。
次第m行、三つの整数VIの第i行、UI、TI(1≤ VI、UI≤nは、0≤TI≤1)、 > UI有向エッジ- VIを表します。0 1 'B'を表し、 'P'を表します。重い側を確保しないように、しかし、自己ループがあるかもしれません。
出力
出力1、> 10 ^ 18の最長の可能な長さであれば、そうでない場合、可能な限り長い長さの出力。

@解決@

最初の2 ^私の文字のために長いフォロー文字(ナンセンス)の後、我々は2 ^(I-1)文字として見ることができる前に行く2 ^(I-1)。

二つのことを維持し、被験者はパスS2の後に否定されたパスPBBPBPPB ... S1、他のタイプBPPBPBBP ...のタイプです。
2 ^(I-1)から2 ^ Iへの移行は、S1 '= S1 + S2、S2有し ' = S2 + S1を。

ノートF [0/1] [I] [ X] [Y]、0/1が第一種又は第二種を示し、Y場合、開始からX 2 ^ I-ステップ歩行に到達することができます。
列挙転送通過点、Fから[0] [I-1 ] [X] [Z] およびF [1]〜[I-1 ] [Z] [Y] Fに転送される[0] [i]は、[ X ] [Y]、F [1]から[I-1 ] [X] [Z] およびF [0] [I-1 ] [z]は[Y]はFに転送される[1]〜[I] [ X] [ Y]。
最後に、iが0 = ... 60は可能な限り長い長さを得るために、乗算の概念を用いて、Fに応じて決定される(ここで、プロセスは、必要なツリーLCAの乗算処理と同様です)。
この複雑さはO(N ^ 3 * logA)であり 、 A = 10 ^ 18。

これはちょうどフロイド推移閉包のようなものですが、私たちはすべてのものは、ビットセットを最適化するために使用することができることを知っており、効果は非常に明白であることに注意してください。
次いで、使用ビットセットした後、複雑さはO(N ^ 3 * logA /に最適化されている W)、 W = 32または64。

@acceptedコード@

#include <cstdio>
#include <bitset>
using namespace std;
bitset<500>bts[2][61][500], nw, tmp;
int main() {
    int n, m; scanf("%d%d", &n, &m);
    for(int i=1;i<=m;i++) {
        int u, v, p; scanf("%d%d%d", &u, &v, &p), u--, v--;
        bts[p][0][u].set(v, 1);
    }
    for(int p=1;p<=60;p++) {
        for(int k=0;k<n;k++)
            for(int i=0;i<n;i++) {
                if( bts[0][p-1][i][k] ) bts[0][p][i] |= bts[1][p-1][k];
                if( bts[1][p-1][i][k] ) bts[1][p][i] |= bts[0][p-1][k];
            }
    }
    int type = 0; nw.set(0, 1);
    long long ans = 0;
    for(int i=60;i>=0;i--) {
        tmp = 0;
        for(int j=0;j<n;j++)
            if( nw[j] && bts[type][i][j].any() )
                tmp |= bts[type][i][j];
        if( tmp.any() ) {
            ans |= (1LL<<i);
            type ^= 1, nw = tmp;
        }
    }
    if( ans > (long long)(1E18) ) puts("-1");
    else printf("%lld\n", ans);
}

詳細@

.JPGとビットセット素敵。

おすすめ

転載: www.cnblogs.com/Tiw-Air-OAO/p/11845922.html