题目描述:
hrek是一个大山里的邮递员,每天负责给所在地区的n个村庄派发信件。但杯具的是,由于道路狭窄,年久失修,村庄间的道路都只能单向通过,甚至有些村庄无法从任意一个村庄到达。这样我们只能希望尽可能多的村庄可以收到投递的信件。
Shrek希望知道如何选定一个村庄A作为起点(我们将他空投到该村庄),依次经过尽可能多的村庄,路途中的每个村庄都经过仅一次,最终到达终点村庄B,完成整个送信过程。这个任务交给你来完成。
输入格式:
第一行包括两个整数n,m,分别表示村庄的个数以及可以通行的道路的数目。
以下共m行,每行用两个整数v1和v2表示一条道路,两个整数分别为道路连接的村庄号,道路的方向为从v1至v2,n个村庄编号为[1, n]。
要求:
1 ≤ n ≤ 1,000,000
0 ≤ m ≤ 1,000,000
输入保证道路之间没有形成环
输出格式:
输出一个数字,表示符合条件的最长道路经过的村庄数。
输入样例:
4 3
1 4
2 4
4 3
输出样例:
3
题解:
//本题的逻辑结构:图
//本题的存储结构:顺序
//解题思路和算法:初始化有向图,按照题给写入顶点和有向边,获取每个点的入度写入数组,深度优先遍历入度为0的点,设置全局变量maxNum,
// 深度遍历的深度最大值如果大于maxNum则赋给maxNum,始终保持maxNum为最大值,最后输出maxNum
//效率:时间复杂度O(n^2)、空间复杂度O(1):
//测试数据: (1)输入:4 3
// 1 4
// 2 4
// 4 3
// 输出:3
// (2)输入:6
// 5
// 1 2
// 2 3
// 2 4
// 4 5
// 2 6
// 输出:4
#include<stdio.h>
#include<malloc.h>
#define MaxVertexNum 100
#define INFINITY 0
#define max(a,b) ((a)>(b)?(a):(b))
typedef int Vertex;
typedef int DataType;
typedef struct GNode * PtrToGNode;
struct GNode
{
/* data */
int Nv;
int Ne;
DataType G[MaxVertexNum][MaxVertexNum];
};
typedef PtrToGNode MGraph;
typedef struct ENode * PtrToENode;
struct ENode
{
/* data */
Vertex V1, V2;
};
typedef PtrToENode Edge;
MGraph CreateGraph(int VertexNum){
Vertex V, W;
MGraph Graph;
Graph = (MGraph) malloc (sizeof(struct GNode));
Graph->Nv = VertexNum;
Graph->Ne = 0;
for(V = 0; V < Graph->Nv; V++){
for(W = 0; W < Graph->Nv; W++){
Graph->G[V][W] = INFINITY;
}
}
return Graph;
}
void InsertEdge(MGraph Graph, Edge E){
Graph->G[E->V1-1][E->V2-1] = 1;
}
MGraph BuildGraph(){
MGraph Graph;
Edge E;
Vertex V;
int Nv, i;
scanf("%d", &Nv);
Graph = CreateGraph(Nv);
scanf("%d", &(Graph->Ne));
if(Graph->Ne!=0){
E = (Edge)malloc(sizeof(struct ENode));
for(i = 0; i<Graph->Ne; i++){
scanf("%d %d", &E->V1, &E->V2);
InsertEdge(Graph, E);
}
}
return Graph;
}
int maxNum=0;
int findN(MGraph G1, int x, int num){
int count = 0;
for(int i=0;i<G1->Nv;i++){
if(G1->G[x][i]){
num = findN(G1, i, ++num);
count++;
}
}
if(!count){
maxNum = max(maxNum, num);
num--;
}
return num;
}
int main(){
MGraph G1 = BuildGraph();
// for(int i = 0; i<G1->Nv;i++){
// for(int j=0;j<G1->Nv;j++){
// printf("%d ", G1->G[i][j]);
// }
// printf("\n");
// }
int arr[G1->Nv];
int find0 = 0;
for(int i = 0; i<G1->Nv;i++){
for(int j=0;j<G1->Nv;j++){
find0 += G1->G[j][i];
}
arr[i] = find0;
if(arr[i]==0){
findN(G1, 0, 0);
}
find0 = 0;
}
printf("%d", maxNum+1);
return 0;
}
// 6
// 5
// 1 2
// 2 3
// 2 4
// 4 5
// 2 6