You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
|
|
#include <bits/stdc++.h>
|
|
|
|
|
|
|
|
|
|
using namespace std;
|
|
|
|
|
const int N = 100010;
|
|
|
|
|
int n; //n个结点
|
|
|
|
|
int m; //m条边
|
|
|
|
|
int res[N];
|
|
|
|
|
int u, v;
|
|
|
|
|
vector<int> p[N]; //vector存图
|
|
|
|
|
/**
|
|
|
|
|
基本思想:
|
|
|
|
|
反向建边是逆向思维,这样dfs时可以通过打标记来更便捷地记录某点所能到达的最大点,
|
|
|
|
|
而正向建边dfs时可能会重复搜索,遍历整个图,会增大复杂度
|
|
|
|
|
|
|
|
|
|
感悟:正向建边TLE时,考虑一下反向建边
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 功能:填充每个结点能够到达的最大结点号
|
|
|
|
|
* @param x 哪个结点
|
|
|
|
|
* @param d 最大结点号
|
|
|
|
|
*/
|
|
|
|
|
void dfs(int x, int d) {
|
|
|
|
|
if (res[x]) return; //访问过
|
|
|
|
|
res[x] = d;
|
|
|
|
|
for (int i = 0; i < p[x].size(); i++) dfs(p[x][i], d);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int main() {
|
|
|
|
|
//读入
|
|
|
|
|
scanf("%d%d", &n, &m);
|
|
|
|
|
//构建图
|
|
|
|
|
for (int i = 1; i <= m; i++) {
|
|
|
|
|
scanf("%d%d", &u, &v);
|
|
|
|
|
p[v].push_back(u); //反向建边
|
|
|
|
|
}
|
|
|
|
|
//从大到小,逐个深度优先搜索
|
|
|
|
|
for (int i = n; i; i--) dfs(i, i);
|
|
|
|
|
//输出每个结点的最大到达结点号
|
|
|
|
|
for (int i = 1; i <= n; i++) printf("%d ", res[i]);
|
|
|
|
|
printf("\n");
|
|
|
|
|
return 0;
|
|
|
|
|
}
|