题目描述
给出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)。
输入输出样例
输入样例#1:
4 3 1 2 2 4 4 3
输出样例#1:
4 4 3 4
说明
• 对于60% 的数据,1≤N.K≤103;
• 对于100% 的数据,1≤N,M≤105。
建一张反图,先从从编号大的点开始走,能走到的所有的点得答案就是这个点。
#include<iostream>
#include<algorithm>
#include<cstring>
#define f(i,l,r) for(i=(l);i<=(r);i++)
#define ff(i,r,l) for(i=(r);i>=(l);i--)
using namespace std;
const int MAXN=100005;
int n,m;
struct Edge{
int v,next;
}e[MAXN];
int head[MAXN],tot,ans[MAXN],vis[MAXN];
inline void add(int u,int v)
{
e[tot].v=v;
e[tot].next=head[u];
head[u]=tot++;
}
inline void dfs(int u,int a)
{
int i;
ans[u]=a;
for(i=head[u];~i;i=e[i].next){
int v=e[i].v;
if(!ans[v]) dfs(v,a);
}
}
int main()
{
ios::sync_with_stdio(false);
memset(head,-1,sizeof(head));
int i,j,u,v;
cin>>n>>m;
f(i,1,m){
cin>>u>>v;
add(v,u);
}
ff(i,n,1){
if(ans[i]) continue;
dfs(i,i);
}
f(i,1,n){
cout<<ans[i]<<' ';
}
cout<<endl;
return 0;
}