数据结构练习 01-图的遍历
题目描述
给出N个点,M条边的有向图,对于每个点v,求A(v)表示从点v出发,能到达的编号最大的点。
输入格式
第1行,2个整数N,M。
接下来M行,每行2个整数Ui,Vi,表示边(Ui,Vi)。点用1,2,⋯,N编号。
输出格式
N个整数A(1),A(2),⋯,A(N)。
输入输出样例
输入
4 3
1 2
2 4
4 3
输出
4 4 3 4
解题思路及代码
首先明确这是一个有向图。
struct Graph {
int vexnum;
vector<vector<int>> adj;
};
该题需要对一个有向图进行遍历,用ans数组来记录每个节点遍历的最大值。其特点是若在一条遍历路径中找到一个最大值,则该最大值之前的所有节点的ans 都应该是这个最大值。换句话说,遍历是沿着路径向前的,但是结果是要向后写的。
最初的解法是从小到大逐个遍历,每次遍历有一个最大值m,若碰到已经有结果的节点,则比较该节点的ans与m的大小,完成所有节点的遍历后得到该节点的ans。
int main() {
Graph g;
int m;
cin >> g.vexnum >> m;
g.adj.resize(g.vexnum);
vector<int> ans(g.vexnum, -1);
for (int i = 0; i < m; i++) {
int a, b;
cin >> a >> b;
g.adj[a - 1].push_back(b - 1);
}
for (int i = 0; i < g.vexnum; i++) {
if (ans[i] > 0) continue;
vector<int> T(g.vexnum, 0);
queue<int> q;
int temp = i;
q.push(i);
T[i] = 1;
while (!q.empty()) {
int f = q.front();
q.pop();
for (int j = 0; j < g.adj[f].size(); j++) {
if (!T[g.adj[f][j]]) {
if (ans[g.adj[f][j]] >= 0) {
if (temp < ans[g.adj[f][j]]) {
temp = ans[g.adj[f][j]];
}
}
else {
if (g.adj[f][j] > temp) {
temp = g.adj[f][j];
}
q.push(g.adj[f][j]);
}
T[g.adj[f][j]] = 1;
}
}
}
ans[i] = temp;
}
for (int i = 0; i < g.vexnum - 1; i++) {
cout << ans[i] + 1 << " ";
}
cout << ans[g.vexnum - 1] + 1;
return 0;
}
该解法有一个明显的缺点是节点重复遍历,当数据量较大时无法在规定时间内完成。因此目标应该是争取能做到一次遍历就能得到结果,尽量少的遍历次数应该是做这类题目的共同特征。
因此可以采取反向建边的思路,即将有向图的方向全部倒置。从值最大的节点开始遍历,每次遍历经过的节点的ans即为该次遍历的开始节点的值。
int main() {
Graph g;
int m;
cin >> g.vexnum >> m;
g.adj.resize(g.vexnum);
vector<int> ans(g.vexnum, -1);
for (int i = 0; i < m; i++) {
int a, b;
cin >> a >> b;
g.adj[b - 1].push_back(a - 1);
}
for (int i = g.vexnum - 1; i >= 0; i--) {
if (ans[i] >= 0) continue;
ans[i] = i;
queue<int> q;
q.push(i);
while (!q.empty()) {
int f = q.front();
q.pop();
for (int j = 0; j < g.adj[f].size(); j++) {
if (ans[g.adj[f][j]] < 0) {
ans[g.adj[f][j]] = i;
q.push(g.adj[f][j]);
}
}
}
}
for (int i = 0; i < g.vexnum - 1; i++) {
cout << ans[i] + 1 << " ";
}
cout << ans[g.vexnum - 1] + 1;
return 0;
}
参考资料
1.洛谷_P3916 图的遍历:https://www.luogu.com.cn/problem/P3916
2.洛谷题解_hongzy 的博客:https://www.luogu.com.cn/blog/hongzy/solution-p3916

浙公网安备 33010602011771号