luogu1613 跑路
题目大意
一个有向图有起点和终点的有向图,你一次可以走过2^k条边,问从起点到终点所需要走的最小次数。k<=31。
思路

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAX_NODE = 55, MAX_DIGIT = 40, INF = 0x3f3f3f3f;
bool Reachable[MAX_NODE][MAX_NODE][MAX_DIGIT];
int Edges[MAX_NODE][MAX_NODE], Dist[MAX_NODE];
int TotNode, TotEdge;
void B_GetReachable()
{
for (int k = 1; k <= 31; k++)
for (int u = 1; u <= TotNode; u++)
for (int v = 1; v <= TotNode; v++)
for (int mid = 1; mid <= TotNode; mid++)
Reachable[u][v][k] |= (Reachable[u][mid][k - 1] && Reachable[mid][v][k - 1]);
}
void GetEdge()
{
memset(Edges, INF, sizeof(Edges));
for (int k = 0; k <= 31; k++)
for (int u = 1; u <= TotNode; u++)
for (int v = 1; v <= TotNode; v++)
if (Reachable[u][v][k])
Edges[u][v] = 1;
}
void Bellman_Ford()
{
memset(Dist, INF, sizeof(Dist));
Dist[1] = 0;
for (int k = 1; k <= TotNode; k++)
for (int u = 1; u <= TotNode; u++)
for (int v = 1; v <= TotNode; v++)
Dist[v] = min(Dist[v], Dist[u] + Edges[u][v]);
}
int main()
{
scanf("%d%d", &TotNode, &TotEdge);
for (int e = 1; e <= TotEdge; e++)
{
int u, v;
scanf("%d%d", &u, &v);
Reachable[u][v][0] = true;
}
B_GetReachable();
GetEdge();
Bellman_Ford();
printf("%d\n", Dist[TotNode]);
return 0;
}

浙公网安备 33010602011771号