题目背景
对应的选择、判断题:试题 - GESP 202503 C++ 七级 - 洛谷有题
题目描述
小 A 有一张包含 n 个结点与 m 条边的无向图,结点以 1,2,...,n 标号。小 A 会从图上选择一个结点作为起点,每一步移动到某个与当前小 A 所在结点相邻的结点。对于每个结点 i (1≤i≤n),小 A 想知道从结点 i 出发恰好移动 1,2,...,k 步之后,小 A 可能会位于哪些结点。由于满足条件的结点可能有很多,你只需要求出这些结点的数量。
输入格式
第一行,三个正整数 n,m,k,分别表示无向图的结点数与边数,最多移动的步数。
接下来 m 行,每行两个正整数 ui,vi,表示图中的一条连接结点 ui 与 vi 的无向边。
输出格式
共 n 行,第 i 行 (1≤i≤n) 包含 k 个整数,第 j 个整数 (1≤j≤k) 表示从结点 i 出发恰好移动 j 步之后可能位置的结点数量。
输入输出样例
输入 #1复制
4 4 3
1 2
1 3
2 3
3 4
输出 #1复制
2 4 4
2 4 4
3 3 4
1 3 3
说明/提示
本题采用捆绑测试。
对于 20% 的测试点,保证 k=1。
对于另外 20% 的测试点,保证 1≤n≤50,1≤m≤50。
对于所有测试点,保证 1≤n≤500,1≤m≤500,1≤k≤20,1≤ui,vi≤n。
代码实现:
cpp
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 505;
const int MAXK = 25;
bool pre[MAXN][MAXN], cur[MAXN][MAXN];
vector<int> g[MAXN];
int ans[MAXN][MAXK];
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n, m, k;
cin >> n >> m >> k;
for (int i = 1; i <= m; i++)
{
int u, v;
cin >> u >> v;
g[u].push_back(v);
g[v].push_back(u);
}
for (int s = 1; s <= n; s++) pre[s][s] = true;
for (int step = 1; step <= k; step++)
{
memset(cur, 0, sizeof(cur));
for (int s = 1; s <= n; s++)
{
for (int u = 1; u <= n; u++)
{
if (pre[s][u])
{
for (int v : g[u])
{
cur[s][v] = true;
}
}
}
}
for (int s = 1; s <= n; s++)
{
int cnt = 0;
for (int t = 1; t <= n; t++) if (cur[s][t]) cnt++;
ans[s][step] = cnt;
}
memcpy(pre, cur, sizeof(cur));
}
for (int s = 1; s <= n; s++)
{
for (int j = 1; j <= k; j++)
{
cout << ans[s][j];
if (j < k) cout << " ";
}
cout << "\n";
}
return 0;
}