给定n个点,m条边的有向图,对于每个点v,求f(v)表示从点v出发能到达的编号最大的点(包括自己在内)。 n,m≤10^5 Input Format 第一行有22个整数n,m。 接下来m行,每行2个整数ui,vi,表示ui到vi有一条边。 点用1,2,⋯,n编号。 Output Format n个整数f(1),f(2),⋯,f(n)用C++实现此问题,不用STL
时间: 2024-02-12 22:07:25 浏览: 184
.有向图计数优化版原理及C++实现
可以使用深度优先搜索(DFS)来解决这个问题。对于每个节点v,我们可以从v开始进行DFS,并记录能够到达的最大节点编号max_v。最后返回max_v作为f(v)的值。
具体实现过程如下:
1. 定义一个全局变量maxn表示图中节点的最大编号,一个数组head和一个结构体Edge表示图的边表。
2. 定义一个结构体Node表示每个节点,包括节点编号id和能够到达的最大节点编号max_id。
3. 定义一个数组vis表示每个节点是否被访问过,初始值为false。
4. 定义一个DFS函数,输入参数为当前节点编号cur和当前能够到达的最大节点编号max_id,遍历当前节点的所有出边,如果该出边指向的节点未被访问过,则递归调用DFS函数,并更新能够到达的最大节点编号max_id。
5. 在主函数中遍历每个节点,如果该节点未被访问过,则调用DFS函数进行遍历,并将遍历得到的能够到达的最大节点编号max_id赋值给该节点的max_id属性。
6. 最后输出每个节点的max_id属性即可。
代码如下:
```c++
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn = 100005;
int n, m, cnt;
int head[maxn];
bool vis[maxn];
struct Edge {
int v, nxt;
} e[maxn];
struct Node {
int id, max_id;
} node[maxn];
void addEdge(int u, int v) {
e[++cnt].v = v;
e[cnt].nxt = head[u];
head[u] = cnt;
}
void DFS(int cur, int max_id) {
vis[cur] = true;
node[cur].max_id = max(node[cur].max_id, max_id);
for (int i = head[cur]; i; i = e[i].nxt) {
int v = e[i].v;
if (!vis[v]) {
DFS(v, node[cur].max_id);
}
}
}
int main() {
scanf("%d%d", &n, &m);
for (int i = 1; i <= m; ++i) {
int u, v;
scanf("%d%d", &u, &v);
addEdge(u, v);
}
for (int i = 1; i <= n; ++i) {
node[i].id = i;
node[i].max_id = i;
}
for (int i = 1; i <= n; ++i) {
if (!vis[i]) {
DFS(i, i);
}
}
for (int i = 1; i <= n; ++i) {
printf("%d ", node[i].max_id);
}
return 0;
}
```
阅读全文