旅行商问题
描述
Shrek是一个大山里的邮递员,每天负责给所在地区的n个村庄派发信件。但杯具的是,由于道路狭窄,年久失修,村庄间的道路都只能单向通过,甚至有些村庄无法从任意一个村庄到达。这样我们只能希望尽可能多的村庄可以收到投递的信件。
Shrek希望知道如何选定一个村庄A作为起点(我们将他空投到该村庄),依次经过尽可能多的村庄,路途中的每个村庄都经过仅一次,最终到达终点村庄B,完成整个送信过程。这个任务交给你来完成。
输入
第一行包括两个整数n,m,分别表示村庄的个数以及可以通行的道路的数目。
以下共m行,每行用两个整数v1和v2表示一条道路,两个整数分别为道路连接的村庄号,道路的方向为从v1至v2,n个村庄编号为[1, n]。
输出
输出一个数字,表示符合条件的最长道路经过的村庄数。
样例
Input
4 3
1 4
2 4
4 3
Output
3
限制
1 ≤ n ≤ 1,000,000
0 ≤ m ≤ 1,000,000
输入保证道路之间没有形成环
时间:2 sec
空间:256 MB
提示
拓扑排序
#include <iostream>
#include <stdio.h>
#include<malloc.h>
using namespace std;
const int Maxlength = 100005;
typedef struct EdgeNode//边表节点的结构体
{
int adjvex;//表示该边的另一个节点对应的下标
//int weight;//保存该边的权值,无权图可以设为1
struct EdgeNode *next;//指针域,指向下一个节点
} EdgeNode;
//----------------------------------------------------------------------------
typedef struct VertexNode//顶点表节点
{
int data;//顶点域,存储顶点信息
EdgeNode *firstedge;//指针域,指向邻接的第一个顶点
} VertexNode;
//----------------------------------------------------------------------------
typedef struct AdjList_Graph//用邻接表存储的图的结构体
{
VertexNode adjlist[Maxlength];//存放顶点域和指针域
int Vnum,Enum;//顶点数和边数,在本案例中未用到边数
} AdjList_Graph;
typedef struct Stack
{
int data[Maxlength];
int top;
} Stack;
int Roads[Maxlength];
int number=1;
int Indegree[Maxlength];
int LocateGraph(AdjList_Graph a,int data)
{
for(int i = 0; i<a.Vnum; i++)
{
if(data == a.adjlist[i].data)
{
return i;//返回的是下标
}
}
}
void CreateAdjList(AdjList_Graph &G)//创建邻接表
{
for(int i =0; i<G.Vnum; i++)
{
G.adjlist[i].data = i+1;
G.adjlist[i].firstedge = NULL;
}
int FirstPoint,SecondPoint,FirstPosition,SecondPosition;
for(int i=0; i<G.Enum; i++)
{
cin>>FirstPoint;
cin>>SecondPoint;
FirstPosition = FirstPoint-1;
SecondPosition =SecondPoint-1;
EdgeNode *e = (EdgeNode*)malloc(sizeof(EdgeNode));//向内存申请空间
e->adjvex = SecondPosition;
//e->weight = 1;
e->next = NULL;//该表节点暂时没有下一个节点
EdgeNode *p = G.adjlist[FirstPosition].firstedge;//将第FPS个顶点的边表头指针赋值给表节点指针p
e->next = G.adjlist[FirstPosition].firstedge;
G.adjlist[FirstPosition].firstedge = e;
// if(p == NULL)//第FPS个顶点的边表结点为空
// {
// G.adjlist[FirstPosition].firstedge = e;//实现两点相连
// }
// else
// {
// while(p->next!=NULL)
// {
// p=p->next;
// }
// p->next=e;
// }
Indegree[SecondPosition]++;
}
}
int isEmpty(Stack *s)
{
if(s->top == -1)
{
return 1;
}
else
{
return 0;
}
}
void initStack(Stack *s)
{
s->top = -1;
}
void push(Stack *s,int data)
{
s->data[++s->top] = data;
}
void pop(Stack *s,int *data)
{
*data = s->data[s->top--];
}
void tuopupaixv(AdjList_Graph *a)
{
Stack s ;
initStack(&s);
for(int i =0; i<a->Vnum; i++)
{
Roads[i] = 1;
}
for(int i = 0; i<a->Vnum; i++)
{
if(Indegree[i] == 0)
{
push(&s,i);
}
}
int position;
while(!isEmpty(&s))
{
pop(&s,&position);
EdgeNode *p = a->adjlist[position].firstedge;
while(p)
{
if(--Indegree[p->adjvex] == 0)
{
push(&s,p->adjvex);
}
if(Roads[position]+1>Roads[p->adjvex])
{
Roads[p->adjvex] = Roads[position]+1;
}
if(number<Roads[p->adjvex])
{
number = Roads[p->adjvex];
}
p = p->next;
}
}
}
//void AdjList_DFS(AdjList_Graph Gr,int StartData)//基于邻接表,从给定顶点深度遍历整个图
//{
// int position = StartData-1;
// EdgeNode *p;
//
// Visited[position] = 1;//访问过的设置为1
// number++;
// //cout<<"DFS:"<<Gr.adjlist[position].data<<" ";
// p = Gr.adjlist[position].firstedge;
// while(p)
// {
// if(Visited[p->adjvex]==0)
// {
// AdjList_DFS(Gr,Gr.adjlist[p->adjvex].data);
// }
// p = p->next;
// }
//}
//void Display_AdjList_Graph(AdjList_Graph G)//输出显示邻接表
//{
// EdgeNode *e;
// cout<<"共有"<<G.Vnum<<"个顶点"<<endl;
// for(int i=0; i<G.Vnum; i++)
// {
// cout<<G.adjlist[i].data<<" ";
// }
// cout<<endl;
// for(int i=0; i<G.Vnum; i++)
// {
// e = G.adjlist[i].firstedge;
// while(e!=NULL)
// {
// cout<<"["<<G.adjlist[i].data<<"->"<<G.adjlist[e->adjvex].data<<"]";
// e = e->next;
// }
// cout<<endl;
// }
//}
int main()
{
//cout<<"请输入图的结点数和边数:";
AdjList_Graph G;
cin>>G.Vnum>>G.Enum;
CreateAdjList(G);
// Display_AdjList_Graph(G);
// cout<<"输出完毕"<<endl;
//AdjList_DFS(G,1);
tuopupaixv(&G);
cout << number << endl;
return 0;
}