@atcoder - AGC036D @負のサイクル


@説明@

0からNまでの番号有向重み付きグラフの所与のNポイント、 - 1。1つのエッジ、iはiおよびiは+ 1点、右側がゼロである点番目のエッジを連結する - このグラフは、スタートNを有しています。

次のこの図フチの各ペアについて(I、J)は、(i≠j)は、偶数I - I <jの> J、-1右側、右側は、そうでなければ1です。

私たちは、エッジの一部(i、j)は(私は≠削除でしょう j)を、 この絵負のループが存在しないことができます。削除コストエッジ(i、j)は(i、j)があります。
リングは図の負に存在しないように、最小コストのパンクチャリングエッジを見つけてください。削除後の唯一のプラス側。

制約
3≤N≤500
1≦(I、J)≦10 9 ^
すべての数字は整数です。

入力
次の形式のフォーマット:
N
A0,1 A0,2 A0,3⋯A0 ,. 1 N-
A1,0 A1,2 A1,3⋯A1 ,. 1 N-
A2,0 A2,1 A2,3 A2⋯、N -1

AN AN-AN⋯AN-1,1-1,0-1,2。1、N-2

出力
出力最小消去コスト。

サンプル入力1
3
2 1
1 4
3 3
サンプル出力1
2

サンプル入力2
4
1 1 1
1 1 1
1 1 1
1 1 1
サンプル出力2
2

@解決@

「私はこのような行為を考えるように起こっていると感じ、私は問題外で逆転、その後ほとんど意味を感じる。」 - LSKことで。

最短存在することを意味し、負のループが存在しない場合。私たちは、最短最初から考える必要があります。
三角不等式:最短は非常に古典的な結論を持っています。すなわち、任意のWの右側縁である(u、v)は常にDISある[U] +> = W DIS [V]。
だから我々は、三角不等式、この質問のさらなる分析からやり直し。

図距離DISのi番目の点への最終点0 [i]のように。[DIS 0の存在の右側縁ので、それはDIS [i]が>は= I + 1]。DISが存在することを特徴とする[0] = 0。
1> = -エッジのI-> J(iはjは<)、DIS [i]が存在するため 、DIS [j]は、I> J(I> J)側では、DISがある[I] + 1> = DIS [J]。
最大DISが三角不等式を満たさなければならないので、負環の非存在下でDIS [I]がある- 1 <= DIS [I + 1]。

間で確立[I + 1] [i]とDIS DISである上記の不平等を指摘し、我々は違いを考慮することができます:P [i]を= DIS [Iみよう ] - DISは、[I + 1]( ないDISことに注意してください。 [I + 1] - DIS [ i])と、 があり、0 <= P [i]が< = 1。
エッジのI-> J(I <jの)ため、満たすべき\(\ sum_ {I} = K-J 1} ^ {P [K] \ GE 1 \。) I-> J(I> J)のために、側は、満たすべき\(\ sum_ {J} = K-Iを1} ^ {P [K] \ル1 \)これは、上記の不等式三角形から推定することができます。
すなわち:間隔の最大を含むように、少なくとも1 1、1ニーズの範囲を含む必要があります。

その後、我々はこのP上のDPことができます。DP [I] [J] [K] iが前処理されたビットを示し、第2の位置に前進1位置jにおける番号1、Kを設定します。
I + 1ビットの列挙は、タイムシフトを埋めるために、0または1として提供されます。最初の次元は、ロールアウトすることができ、明らかです。
Oの時間複雑さ(N ^ 3)。

@acceptedコード@

#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;
const int MAXN = 500;
const ll INF = ll(1E18);
int A[MAXN + 5][MAXN + 5], B[MAXN + 5][MAXN + 5], n;
// A[i][j] -> (p[i] + p[i+1] + ... p[j] >= 1) (i <= j)
// B[i][j] -> (p[i] + p[i+1] + ... p[j] <= 1) (i <= j)
ll SA[MAXN + 5][MAXN + 5], SB[MAXN + 5][MAXN + 5];
// SA[i][j] -> A[1][j] + A[2][j] + ... + A[i][j]
// SB[i][j] -> B[1][j] + B[2][j] + ... + B[i][j]
ll dp[2][MAXN + 5][MAXN + 5], f[2][MAXN + 5], g[2];
int main() {
    scanf("%d", &n);
    for(int i=1;i<=n;i++) {
        for(int j=1;j<=i-1;j++) scanf("%d", &B[j][i-1]); // i -> j (i > j)
        for(int j=i+1;j<=n;j++) scanf("%d", &A[i][j-1]);
    }
    for(int j=1;j<=n;j++)
        for(int i=1;i<=n;i++)
            SA[i][j] = A[i][j] + SA[i-1][j], SB[i][j] = B[i][j] + SB[i-1][j];
    n--;
    for(int j=1;j<=n;j++) {
        for(int k=j+1;k<=n;k++)
            dp[0][j][k] = INF;
        f[0][j] = INF;
    }
    g[0] = 0;
    for(int i=1;i<=n;i++) {
        for(int j=1;j<i;j++) {
            for(int k=j+1;k<i;k++)
                dp[1][j][k] = dp[0][j][k], dp[0][j][k] = INF;
            f[1][j] = f[0][j], f[0][j] = INF;
        }
        g[1] = g[0], g[0] = INF;
        for(int j=1;j<i;j++) {
            for(int k=j+1;k<i;k++) {
                dp[0][j][k] = min(dp[0][j][k], dp[1][j][k] + SA[i][i] - SA[k][i] + SB[j][i]);
                dp[0][k][i] = min(dp[0][k][i], dp[1][j][k] + SB[k][i]);
            }
            f[0][j] = min(f[0][j], f[1][j] + SA[i][i] - SA[j][i]);
            dp[0][j][i] = min(dp[0][j][i], f[1][j] + SB[j][i]);
        }
        g[0] = min(g[0], g[1] + SA[i][i]);
        f[0][i] = min(f[0][i], g[1]);
    }
    ll mn = INF;
    for(int j=1;j<=n;j++) {
        for(int k=j+1;k<=n;k++)
            mn = min(mn, dp[0][j][k]);
        mn = min(mn, f[0][j]);
    }
    mn = min(mn, g[0]);
    printf("%lld\n", mn);
}

@詳細@

転送を容易にするために、1月1日は、任意の状態が含まれていないだけで、数でマルチセット。

私たちは長い長い間、私は意志開いていない場合、私は次の時間。

おすすめ

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