羅区P1613足

\(\大\ textbf {説明:} \ {N図のエッジに点Mを有し、右側が毎秒2 ^ {K}回実行することができ、足1キロを有する大きいです。 KM2は、最短時間は、nに1である。(N \ 50当量、M \当量10000)} \)

\(\大\ textbf {解決法:} \大は{簡単倍増を考えることが、私はLCAを求めているの倍加時間\\思い出を理解し、問題を解決した後に見えたんする方法を見つけ出すために起動しなかった、2 ^ K ^ 2を行うことができます。 {K - 1}転移がように配置ブール変数\ jへのテキスト{DIS [I] [J] [K]} \\ iは、次に簡単に取得するために、2 ^ {K}の経路長が存在するかどうかを示す\テキスト{DIS [I] [J] [K] = DIS [i]が[P] [K-1] && DIS [P] [J] [K-1]}。\\そこiとjの間の場合kが右サイドラインに直接ラン\テキスト{フロイド}であり、真である。} \)

\(\大\ textbf {コード:} \)

#include <bits/stdc++.h>
#define gc() getchar()
#define LL long long
using namespace std;
const int N = 55;
const int inf = 0x7fffffff;
int n, m, g[N][N], dis[N][N][65];

inline int read() {
	char ch = gc();
	int ans = 0, flag = 1;
	while (!isdigit(ch)) ch = gc(); 
	while (isdigit(ch)) ans = ans * 10 + ch - '0', ch = gc();
	return ans * flag;	
}

int main() {
	n = read(), m = read();
	int x, y;
	for (int i = 1; i <= n; ++i) for (int j = 1; j <= n; ++j) g[i][j] = 20;
	while (m--) x = read(), y = read(), g[x][y] = 1, dis[x][y][0] = 1;
	for (int i = 1; i <= 64; ++i)
		for (int j = 1; j <= n; ++j)
			for (int k = 1; k <= n; ++k)
				for (int p = 1; p <= n; ++p)
					if (dis[j][k][i - 1] && dis[k][p][i - 1]) dis[j][p][i] = 1, g[j][p] = 1;
	for (int k = 1; k <= n; ++k)
		for (int i = 1; i <= n; ++i)
			for (int j = 1; j <= n; ++j)
				g[i][j] = min(g[i][j], g[i][k] + g[k][j]);
	cout << g[1][n] << endl;
	return 0;
}

おすすめ

転載: www.cnblogs.com/Miraclys/p/12559972.html
おすすめ