P3916 图的遍历

题目描述

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

输入格式

第 11 行 22 个整数 �,�N,M,表示点数和边数。

接下来 �M 行,每行 22 个整数 ��,��Ui​,Vi​,表示边 (��,��)(Ui​,Vi​)。点用 1,2,…,�1,2,…,N 编号。

输出格式

一行 �N 个整数 �(1),�(2),…,�(�)A(1),A(2),…,A(N)。

输入输出样例

输入 #1复制

4 3
1 2
2 4
4 3

输出 #1复制

4 4 3 4

说明/提示

  • 对于 60%60% 的数据,1≤�,�≤1031≤N,M≤103。
  • 对于 100%100% 的数据,1≤�,�≤1051≤N,M≤105。

1.该题我采用的是dfs算法。

2.先根据输入的顶点建立一个邻接表。

3.遍历每一个点进行深搜,每一次用一个max记录下该点可以到达的最大编号的点的编号然后输出。

#include"stdio.h"
#include"stdlib.h"
#define MAX 100005
struct bb
{
	int data;
	struct bb *next;
};
typedef struct dd
{
	int data;
	struct bb *firstpoint;
}blist[MAX];
struct graph
{
	int b,d;
	blist A;
};
int M(int a,int b)
{
	if(a>b) return a;
	else return b;
}
int vis[MAX],max;
void dfs(struct graph *G,int i)
{
	int j,k;
    struct bb *p;
    k=G->A[i].data;
    p=G->A[i].firstpoint;
    max=M(max,k); 
    while(p)
    {
    	dfs(G,p->data);
    	p=p->next;
	}
}
main()
{
	int i,j,v,u;
	struct bb *e;
	struct graph G;
	scanf("%d %d",&G.d,&G.b);
	for(i=1;i<=G.d;i++)
	{
		G.A[i].data=i;
		G.A[i].firstpoint=NULL;
	}
	for(i=1;i<=G.b;i++)
	{
		scanf("%d %d",&v,&u);
		e=(struct bb*)malloc(sizeof(struct bb));
		e->data=u;
		e->next=G.A[v].firstpoint;
		G.A[v].firstpoint=e;
	}
	for(i=1;i<=G.d;i++)
	{
		max=0;
		dfs(&G,i);
		printf("%d ",max);
	}	
}

 

你可能感兴趣的:(深度优先,算法,图论)