图的遍历 洛谷p3916

题目描述

给出NN个点,MM条边的有向图,对于每个点vv,求A(v)A(v)表示从点vv出发,能到达的编号最大的点。

输入输出格式

输入格式:

第1 行,2 个整数N,MN,M

接下来MM行,每行2个整数U_i,V_iUi,Vi,表示边(U_i,V_i)(Ui,Vi)。点用1, 2,\cdots,N1,2,,N编号。

输出格式:

N 个整数A(1),A(2),\cdots,A(N)A(1),A(2),,A(N)

输入输出样例

输入样例#1:
4 3
1 2
2 4
4 3
输出样例#1:
4 4 3 4

说明

• 对于60% 的数据,1 \le N . K \le 10^31N.K103

• 对于100% 的数据,1 \le N , M \le 10^51N,M105



建一张反图,先从从编号大的点开始走,能走到的所有的点得答案就是这个点。

#include
#include
#include
#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<


你可能感兴趣的:(图论)