题目描述(P3916):给定有N个节点、M条边的有向图,对每个节点v都求A(v),表示从节点v出发,能到达的编号最大的节点。
输入:第1行包含两个整数N、M(1≤N,M≤105)。接下来的M行,每行都包含两个整数u、v,表示边(u,v)。节点的编号为1~N。
输出:N个整数A(1),A(2),⋯,A(N)。
#include<iostream>
#include<cstring>
#include<queue>
#include<algorithm>
#include<cstdio>
using namespace std;
const int N = 110, M = 110; //N为点 M为边
int n, m;
struct Edge { int to, w, next;};
Edge edge[M];//边集数组:edge[],edge[i]表示第i条边。
int head[N];//头节点数组:head[],head[i]存储以i为起点的第1条边的下标(edge[]中的下标)。
int cnt;
void add(int u, int v) {
edge[cnt].to = v;
edge[cnt].next = head[u];
head[u] = cnt++;
}
int maxu[N];
void dfs(int u, int v) {
if (maxu[v]) return;
maxu[v] = u;//
for (int i = head[v]; i != -1; i = edge[i].next) {
int v1 = edge[i].to;
int w = edge[i].w;
dfs(u, v1);
}
}
int main() {
ios_base::sync_with_stdio(false);
cin >> n >> m;
memset(head, -1, sizeof(head));
for (int i = 0; i < m; i++) {
int u, v;
cin >> u >> v;
add(v, u);//逆向图
}
for (int i = n; i > 0; --i) {
dfs(i, i);
}
for (int i = 1; i <= n; ++i) {
cout << i << ": " << maxu[i] << endl;
}
return 0;
}