题目描述
给出N个点,M条边的有向图,对于每个点v,求A(v)表示从点v出发,能到达的编号最大的点。
输入格式
第1 行,2 个整数N,M。
接下来M行,每行2个整数Ui,Vi,表示边(Ui,Vi)。点用1,2,⋯,N编号。
输出格式
N 个整数A(N)A(1),A(2),⋯,A(N)。
输入输出样例
输入 #1
4 3 1 2 2 4 4 3
输出 #1
4 4 3 4
说明/提示
• 对于60% 的数据,1≤N.M≤103;
• 对于100% 的数据,1≤N,M≤105。
题目解析:
题目要求的是从每个点出发,能够到达的编号最大的点
第一行输入的n,m 其中n表示总共有n个编号,m表示接下来要再输入m行
接下来m行,每行的两个点u,v表示相连接的两个点(即一条边)
要求从每个点出发,能够到达的编号最大的点
这道题用反向建边+dfs做,通过考虑较大的点能够反向到达哪些点更简便
从n到i,每个点i能访问到的结点的a值就是i
再用dfs遍历每一个点,得到最优的a值就可以
代码:
#include <iostream> #include <vector> using namespace std; int n,m,a[100001]; vector<int> g[100001]; void dfs(int x,int d) { if(a[x]) return;//a[x]!=0,即a[x]已经访问过 a[x]=d; for(int i=0;i<g[x].size();i++) dfs(g[x][i],d);//一个个找 } int main() { int u,v,i; cin>>n>>m; for(i=0;i<m;i++) { cin>>u>>v; g[v].push_back(u);//反向建边 } for(i=n;i>0;i--) dfs(i,i); for(i=1;i<=n;i++) cout<<a[i]<<" "; return 0; }