【Tsinghua Online Judge】旅行商(TSP)-拓扑排序求大路径
2015-12-28 14:08
549 查看
旅行商(TSP)
Description
Shrek is a postman working in the mountain, whose routine work is sending mail to n villages. Unfortunately, road between villages is out of repair for long time, such that some road is one-way road. There are evensome villages that can’t be reached from any other village. In such a case, we only hope as many villages can receive mails as possible.
Shrek hopes to choose a village A as starting point (He will be air-dropped to this location), then pass by as many villages as possible. Finally, Shrek will arrived at village B. In the travelling process, each
villages is only passed by once. You should help Shrek to design the travel route.
Input
There are 2 integers, n and m, in first line. Stand for number of village and number of road respectively.In the following m line, m road is given by identity of villages on two terminals. From v1 to v2. The identity of village is in range [1, n].
Output
Output maximum number of villages Shrek can pass by.
Example
Input4 3 1 4 2 4 4 3
Output
3
Restrictions
1 <= n <= 1,000,0000 <= m <= 1,000,000
These is no loop road in the input.
Time: 2 sec
Memory: 256 MB
Hints
Topological sorting
描述
Shrek是一个大山里的邮递员,每天负责给所在地区的n个村庄派发信件。但杯具的是,由于道路狭窄,年久失修,村庄间的道路都只能单向通过,甚至有些村庄无法从任意一个村庄到达。这样我们只能希望尽可能多的村庄可以收到投递的信件。Shrek希望知道如何选定一个村庄A作为起点(我们将他空投到该村庄),依次经过尽可能多的村庄,路途中的每个村庄都经过仅一次,最终到达终点村庄B,完成整个送信过程。这个任务交给你来完成。
输入
第一行包括两个整数n,m,分别表示村庄的个数以及可以通行的道路的数目。以下共m行,每行用两个整数v1和v2表示一条道路,两个整数分别为道路连接的村庄号,道路的方向为从v1至v2,n个村庄编号为[1, n]。
输出
输出一个数字,表示符合条件的最长道路经过的村庄数。
样例
见英文题面
限制
1 ≤ n ≤ 1,000,0000 ≤ m ≤ 1,000,000
输入保证道路之间没有形成环
时间:2 sec
空间:256 MB
提示
拓扑排序思路:这道题提示使用拓扑排序,可以在拓扑排序的过程中使用动态规划的思想不断更新结点的最大路径,对于结点U,V来说,设V为U的后继,则有V-max = MAX(V-cur,U-max+1);其中V-max表示结点V的最大路径,V-cur表示结点V的当前路径长度(初始为1),在进行拓扑排序遍历的过程中,不断的更新每个入度为0的结点的后继结点的最大路径长度,最终得到该图的最大路径长度,代码如下:
#include <iostream> #include <cstdio> #include <cstdlib> #define MAX 1000000 #define GETMAX(x,y) ((x) > (y) ? (x):(y)) using namespace std; //使用邻接表存储图 struct EdgeNode /*边表结点*/ { int adjvex; //存储邻接顶点对应下标 int length;//到该结点路径长度 struct EdgeNode *nex;//指向下一个邻接点 }; struct VertexNode //顶点表结点 { int in; //顶点入度 int data;//数据 int length;//到该结点路径长度 EdgeNode *firstEdge;//边表头指针 }; struct Graph { VertexNode adjList[MAX];//顶点数组 int numVertexs;//顶点数 int numEdges;//边数 }graph; int maxLength = 1; VertexNode topSort[MAX];//保存拓扑排序结果 int main() { int n,m,a,b; scanf("%d%d",&n,&m); graph.numEdges = m; graph.numVertexs = n; for(int i=0;i<n;i++)//初始化顶点数组 { graph.adjList[i].data = i+1; graph.adjList[i].in = 0; graph.adjList[i].length = 1; graph.adjList[i].firstEdge = NULL; } for(int i = 0;i<m;i++)//输入边信息并构建邻接表(拓扑排序) -邻接矩阵(最长路径) { scanf("%d%d",&a,&b);//输入边的端点 EdgeNode *e = new EdgeNode; e->adjvex = b-1;//数组下标从0开始 graph.adjList[b-1].in++;//b结点入度加1 e->nex = NULL; EdgeNode *p = graph.adjList[a-1].firstEdge; if(p == NULL) { graph.adjList[a-1].firstEdge = e; } else { while (p->nex != NULL) { p = p->nex; } p->nex = e; } } int stack[MAX];//拓扑排序时保存入度为0的结点堆栈 int stk[MAX];//保存初始入度为0结点 int top = 0,index,num=0,t=0; EdgeNode *e; for(int i=0;i<graph.numVertexs;i++) { if(graph.adjList[i].in == 0) { stack[top++] = i;//保存结点在数组中的下标 stk[num++] = i;//入度为0结点数 } } while(top!=0)//进行拓扑排序 { index = stack[--top];//出栈,取出入度为零的结点 for(e = graph.adjList[index].firstEdge;e!=NULL;e=e->nex)//遍历该结点的边表 { int tempindex = e->adjvex; //动态规划-更新其后继结点的最大路径长度 graph.adjList[tempindex].length = GETMAX(graph.adjList[index].length+1, graph.adjList[tempindex].length); maxLength = GETMAX(graph.adjList[tempindex].length,maxLength); graph.adjList[tempindex].in--;//将邻接点的入度减1 if(graph.adjList[tempindex].in == 0) { stack[top++] = tempindex;//入度为0入栈 } } } printf("%d",maxLength); return 0; }
提交结果如下图:
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- 关于指针的一些事情
- c++ primer 第五版 笔记前言
- share_ptr的几个注意点
- C#数据结构之顺序表(SeqList)实例详解
- Lua中调用C++函数示例
- Lua教程(一):在C++中嵌入Lua脚本
- Lua教程(七):数据结构详解
- Lua教程(二):C++和Lua相互传递数据示例
- 解析从源码分析常见的基于Array的数据结构动态扩容机制的详解
- C#数据结构之队列(Quene)实例详解
- C#数据结构揭秘一
- C#数据结构之单链表(LinkList)实例详解
- C++联合体转换成C#结构的实现方法
- C++编写简单的打靶游戏
- C++ 自定义控件的移植问题
- C++变位词问题分析
- C/C++数据对齐详细解析
- C++基于栈实现铁轨问题
- C++中引用的使用总结