4117:【GESP2503七级】图上移动

0 阅读2分钟

4117:【GESP2503七级】图上移动

时间限制: 1000 ms         内存限制: 131072 KB
提交数:210    通过数: 97

【题目描述】

小 A 有一张包含nn 个结点与mm 条边的无向图,结点以1,2,...,n1,2,...,n 标号。小 A 会从图上选择一个结点作为起点,每一步移动到某个与当前小 A 所在结点相邻的结点。对于每个结点ii (1≤i≤n1≤i≤n ),小 A 想知道从结点ii 出发恰好移动1,2,...,k1,2,...,k步之后,小 A 可能位于哪些结点。由于满足条件的结点可能有很多,你只需要求出这些结点的数量。

【输入】

第一行,三个正整数n,m,kn,m,k ,分别表示无向图的结点数与边数,最多移动的步数。

接下来mm 行,每行两个正整数ui,viui,vi ,表示图中的一条连接结点uiui 与vivi 的无向边。

【输出】

共nn 行,第ii 行(1≤i≤n1≤i≤n )包含kk 个整数,第jj 个整数(1≤j≤k1≤j≤k )表示从结点ii 出发恰好移动jj 步之后可能位于的结点数量。

【输入样例】

4 4 3
1 2
1 3
2 3
3 4

【输出样例】

2 4 4
2 4 4
3 3 4
1 3 3

【提示】

数据范围

对于20 % 的测试点,保证k=1k=1 。

对于另外20 % 的测试点,保证1≤n≤501≤n≤50 ,1≤m≤501≤m≤50 。

对于所有测试点,保证1≤n≤5001≤n≤500 ,1≤m≤5001≤m≤500 ,1≤k≤201≤k≤20 ,1≤ui,vi≤n1≤ui,vi≤n1≤ui,vi≤n 。

【题解】 #include <bits/stdc++.h> //copy using namespace std; vector g[10005]; bool vis[10005]; //标记是否访问,防止重复计算 int cnt[10005][30]; //统计答案

//pos fa k 分别代表当前位置 祖先节点 第k步 void dfs(int pos , int fa , int k) { for (int i = 0 ; i < g[pos].size() ; i++) { int to = g[pos][i]; if (vis[to]) continue; //访问过就跳过,防止重复遍历 vis[to] = true; //标记已访问 cnt[fa][k]++; dfs(to,fa,k+1); } }

int main() { int n,m,k; cin >> n >> m >> k; for (int i = 1 ; i <= m ; i++) { int u,v; cin >> u >> v; //建立分层图,上层与下层通过单向路径连接 for (int j = 0 ; j < k ; j++) { // 第j层 int u1 = u + j * n; int v1 = v + j * n;

        // 第j+1层
        int u2 = u + (j+1) * n;
        int v2 = v + (j+1) * n;

        g[u1].push_back(v2);
        g[v1].push_back(u2);
    }
}

for (int i = 1 ; i <= n ; i++) {
    memset(vis,0,sizeof(vis)); //重置标记数组
    dfs(i,i,1);
    for (int j = 1 ; j <= k ; j++) cout << cnt[i][j] << " ";
    cout << endl;
}

}