[洛谷]P3916 图的遍历 (#图论 -1.1)(#搜索 -3.1)

版权声明:JCBP工作室 & A.pro https://blog.csdn.net/Apro1066/article/details/82833103

题目描述

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

输入输出格式

输入格式:

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

接下来MM行,每行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≤10^3;

• 对于100% 的数据,1≤N,M≤10^5。


思路

刚学图论。。直接dfs肯定错,这是有向图的遍历,遍历顺序是与存边顺序有关的。此题看了一下题解,都说图反向建边然后搜索遍历。有多个点到一个点可以转成一个点到多个点(反向),每个点都搜一次。

这个代码是我借鉴别人的。有部分注释没写是因为不是很理解。以后理解了就补上。

#include <stdio.h>
#include <iostream>
using namespace std;
int n,m,s;
int a[100001],b[100001],to[100001],visit[100001];
void dfs(int now,int i)//i记录初始点,now是现在的点 
{
	register int j;
	if(visit[now])//这个点被访问过了 
	{
		return;
	}
	visit[now]=i;//现在就访问当前的点 
	for(j=b[now];j;j=a[j])
	{
		if(visit[to[j]]==0)
		{
			dfs(to[j],i);
		}
	}
}
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	int x,y,i,j;
	cin>>n>>m;//输入n个点,m条边 
	for(i=1,s=1;i<=m;i++,s++)//开始建立有向图 
	{
		cin>>x>>y;
		a[s]=b[y];//建图 
		b[y]=s;
		to[s]=x;//这是有向图,所以需要方向记录 
	}
	for(i=n;i>=1;i--)//反向找最大点 
	{
		dfs(i,i);
	}
	for(i=1;i<=n;i++)
	{
		cout<<visit[i]<<' ';
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/Apro1066/article/details/82833103
今日推荐