P1613足の問題解決

今日は、本当に何もありませんそれから私は孟バーを販売します(〜¯▽¯)〜

Luogu

思考の問題大物は明らかであるのは、私だけのためであり得ます


問題の意味を簡素化

それはパスをビットにするパスを見つけ、あなたのマップを与える(1 \)\の最小数を

分析

このトピックの質問には、2つのピットがありますおそらく、私だけのために

  1. 以下からの道路があればどこへ行くたびに、あなただけは、つまり、エンドポイントで停止することができます\(私は\)する(Jを\)\は、7のそのパスの長さが、ないからあれば\(I \)に直接行きますする(J \)を\、あなたが行く(3 \)\回。

  2. 以来\(1 \)ので、直接、最短パスが必ずしも最善ではありません実行します。

その後、溶液を考えます

まず、ラベル〜/パスが~~ *徒歩で道のマシンの特殊/牛長すぎるので、我々はこの問題を解決するために、乗算を使用するのではと思ったので、

そして、この最後の質問は、ほとんどの短絡要件であることを検討してください。私たちは、データ範囲を見ることができます\(N - <= 50 \)を、私はフロイトは、最短経路を見つけると思います。しかし、上記の結論に、私たちは直接、最短を実行することはできませんので、我々は、このマップに変換を行う必要があります。この質問は、ポイントの数値に変換することは困難であるので、我々はエッジ/パスへの変換を行うことにしました。

そして、パスの変換を考えます。その理由は、直接検討する前に、最短パスを実行することはできません。私たちは、時間の比較的短い期間でバイナリビットのパスを指示する方法を決定することはできません\(1 \)以下の数なので、我々はバイナリでの貢献の道にそれを置くとき\(1 \)最短数あなたが数えることができます。

前処理したがって、第1 \(Iは\)する(J \)\最短経路(1 \)\の数を、次いでなどの最短辺を求めます。

シークのために(私は\)\をする(J \)\最短パス\(1 \)ので番号を、\は、(私は\)する(J \)\パス特性を有していますああ、私は特定の名前がわかりません:\ (私は\)する(Tは\)\の数で\(K \) \(T \)する\(J \)の数で\(K \) 次いで\(Iは\)\(J \)\(1 \)の数である(K + 1 \)\しますしたがって、我々は、ビン内の閉鎖を見つけるために、各2点間の類似送信最短の方法を使用することができる\(1 \)番号


コード

#include<iostream>
#include<cstring>
using namespace std;
int n,m,x,y,dis[55][55];
bool map[55][55][65];
inline void pre(){
    for(register int t=0;t<=64;t++)
        for(register int k=1;k<=n;k++)
            for(register int i=1;i<=n;i++)
                for(register int j=1;j<=n;j++)
                    if(map[i][k][t-1]&&map[k][j][t-1])
                        map[i][j][t]=1,dis[i][j]=1;
}
inline void floyed(){
    for(register int k=1;k<=n;k++)
        for(register int i=1;i<=n;i++)
            for(register int j=1;j<=n;j++)
                dis[i][j]=min(dis[i][k]+dis[k][j],dis[i][j]);
}
int main(){
    scanf("%d%d",&n,&m);
    memset(dis,0x3f,sizeof(dis));
    for(register int i=1;i<=m;i++)
        scanf("%d%d",&x,&y),
        dis[x][y]=1,map[x][y][0]=1;
    pre();floyed();printf("%d",dis[1][n]);
}

あなたの注意のために最後に、国際的な慣行、ありがとう

おすすめ

転載: www.cnblogs.com/fallen-down/p/11589151.html