做这道题感觉异常激动,因为在下第一次接触拓扑排序啊= =,而且看了看解释,猛然发现此题可以用DP优化,然后一次A掉所有样例,整个人激动坏了,哇咔咔咔咔咔咔咔~ 咔咔~哎呀,笑岔了- -||


旅行商(TSP)


描述

Shrek是一个大山里的邮递员,每天负责给所在地区的n个村庄派发信件。但杯具的是,由于道路狭窄,年久失修,村庄间的道路都只能单向通过,甚至有些村庄无法从任意一个村庄到达。这样我们只能希望尽可能多的村庄可以收到投递的信件。

Shrek希望知道如何选定一个村庄A作为起点(我们将他空投到该村庄),依次经过尽可能多的村庄,路途中的每个村庄都经过仅一次,最终到达终点村庄B,完成整个送信过程。这个任务交给你来完成。

输入

第一行包括两个整数n,m,分别表示村庄的个数以及可以通行的道路的数目。

以下共m行,每行用两个整数v1和v2表示一条道路,两个整数分别为道路连接的村庄号,道路的方向为从v1至v2,n个村庄编号为[1, n]。

输出

输出一个数字,表示符合条件的最长道路经过的村庄数。

Example

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

提示

拓扑排序


  手记部分:

  刚开始做这道题的时候,我不知道有拓扑排序,一直在想结点10^6的图该怎么操作,所以第一个想法就是邻接表,用一个Vetor和一个数组模拟邻接表,之后考虑到在单向寻找最长路的时候应该怎样做优化。最开始的想法是深度优先搜索(DFS),甚至考虑了广度优先搜索(BFS),但是无论怎样都需要O(n^2)的时间度,无疑要么考虑优化,要么改变算法,然后猛然间发现题目下面的提示-拓扑排序- -||,博主顿时觉得脑残了~

  然后博主开始找拓扑排序相关资料,还好有本学长借我的一本图论书,看完概念后理解了AOV和AOE网络以及拓扑排序的基本概念,但对这道题我还是有点迷糊,因为直接排序无疑会破坏邻接表,后来才想到用数组存放拓扑排序后的下标,后来发现这个数组其实就是一种队列,这样就不会破坏编号顺序和邻接表。之后准备开始写主算法的时候原来考虑的是用DFS+优化,后来突然发现每座城市经拓扑排序后,有一种状态满足无后效性——从起始城市到此城市所经过的最大城市数。

  有了这个想法之后就在拓扑排序的基础上(具体算法写在了拓扑排序函数内),完成了DP算法。

  因此这道题目,我的方法就是邻接表(图的保存和查找)+队列(保存拓扑排序)+DP(时间优化)+拓扑排序(完成AOV网络的结点排序)


  以上为博主胡言乱语= =||,直接看懂代码比较容易懂。

  

  

 //TshingHua OJ 旅行商(TSP)
//邻接表+DP+队列+拓扑排序
//Memory:66304KB Time:1101Ms(No.17)
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std; #define MAX 1000005
#define Max(x,y) ((x)>(y)?(x):(y)) int n, m; //村庄个数-道路数
int topology[MAX],lt; //拓扑数组-长度
int mark[MAX]; //入度标记
int maxCity = ; //答案 //从City通向的村庄
struct Node{
int num; //村庄编号
Node *next;
Node(){ next = NULL; }
Node(int x,Node *n) :num(x),next(n){}
}; struct City{
Node *nc; //next-city
int dp; //至此可通过的最大城市数
City(){ nc = NULL; dp = ; }
void insert(int nc);
}city[MAX]; void City::insert(int nc)
{
mark[nc]++; //直接后继城市入度+1
if (this->nc == NULL)
this->nc = new Node(nc,NULL);
else{
Node *node = new Node(nc,this->nc);
this->nc = node;
}
return;
} /*拓扑排序*/
void Topology()
{
for (int i = ; i <= n; i++)
if (!mark[i]) topology[++lt] = i; //入度为0的city
//Main Content
for (int i = ; topology[i];i++)
{
int cur = topology[i]; //该city-number
//遍历该city所有直接后继
for (Node *tmp = city[cur].nc; tmp != NULL; tmp = tmp->next)
{
//此处满足无后效性-DP
city[tmp->num].dp = Max(city[cur].dp + , city[tmp->num].dp);
maxCity = Max(city[tmp->num].dp, maxCity);
//处理后继
int num = tmp->num;
mark[num]--; //后继入度-1
if (!mark[num]) topology[++lt] = num; //若后继入度为0
}
}
} int main()
{
scanf("%d%d", &n, &m);
for (int i = ; i < m; i++)
{
int x, y; //x->y
scanf("%d%d", &x, &y);
city[x].insert(y);
}
/*拓扑排序*/
Topology();
printf("%d\n", maxCity); return ;
}

小墨 - - 原创


ACM/ICPC 之 数据结构-邻接表+DP+队列+拓扑排序(TSH OJ-旅行商TSP)的更多相关文章

  1. ACM/ICPC 之 数据结构-邻接表+BFS(TSH OJ-无线广播Broadcast)

    这道题中若能够构成互不干扰的区域,其构成的图其实就是汉密尔顿路(Hamilton road),因此如果能够观察出来可以直接转化为汉密尔顿路的存在性证明,即便不能观察,我相信ACMer也能转化为BFS问 ...

  2. 确定比赛名次(map+邻接表 邻接表 拓扑结构 队列+邻接表)

    确定比赛名次 Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 65536/32768K (Java/Other) Total Submis ...

  3. HDU 5000 2014 ACM/ICPC Asia Regional Anshan Online DP

    Clone Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 65536/65536K (Java/Other) Total Submiss ...

  4. 08-图8 How Long Does It Take(25 分)邻接表和队列

    Given the relations of all the activities of a project, you are supposed to find the earliest comple ...

  5. 算法与数据结构(七) AOV网的拓扑排序

    今天博客的内容依然与图有关,今天博客的主题是关于拓扑排序的.拓扑排序是基于AOV网的,关于AOV网的概念,我想引用下方这句话来介绍: AOV网:在现代化管理中,人们常用有向图来描述和分析一项工程的计划 ...

  6. 算法与数据结构(七) AOV网的拓扑排序(Swift版)

    今天博客的内容依然与图有关,今天博客的主题是关于拓扑排序的.拓扑排序是基于AOV网的,关于AOV网的概念,我想引用下方这句话来介绍: AOV网:在现代化管理中,人们常用有向图来描述和分析一项工程的计划 ...

  7. hdu 5098 双队列拓扑排序

    http://acm.hdu.edu.cn/showproblem.php?pid=5098 软件在安装之后需要重启才能发挥作用,现在给你一堆软件(有的需要重启有的不需要)以及安装这个软件之前需要哪些 ...

  8. 数据结构之---C语言实现拓扑排序AOV图

    //有向图的拓扑排序 //杨鑫 #include <stdio.h> #include <stdlib.h> #include <string.h> #define ...

  9. [ACM] POJ 1094 Sorting It All Out (拓扑排序)

    Sorting It All Out Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 26801   Accepted: 92 ...

随机推荐

  1. scala入门教程:scala中的面向对象定义类,构造函数,继承

    我们知道scala中一切皆为对象,函数也是对象,数字也是对象,它是一个比java还要面向对象的语言. 定义scala的简单类 class Point (val x:Int, val y:Int) 上面 ...

  2. js jquery, jquery-ui 获取form各种表单input的值?

    如何获取? make up (for): 弥补, 补偿, her beaty cannot make up for her stu'pidity. five Basic laws of human s ...

  3. 使用/调用 函数的时候, 前面加不加 对象或 this?

    这个问题, 其实没有细想: 应该是这样的: (想明白了, 就会少很多困惑, 会对语言的把握 会 更深入更透彻) 任何一门 语言, (如果你自己去设计一门语言...). 都要规定 一些 "关键 ...

  4. css外边距合并和z-index的问题

    参考这篇文章, 将外边距的 折叠 参考这篇文章, 将bfc的生成, bfc的应用 参考这篇文章 position: absolute的元素, 仍然具有内填充padding和border边框属性样式, ...

  5. jQuery1.9.1源码分析--数据缓存Data模块

    jQuery1.9.1源码分析--数据缓存Data模块 阅读目录 jQuery API中Data的基本使用方法介绍 jQuery.acceptData(elem)源码分析 jQuery.data(el ...

  6. 深入浅出的javascript的正则表达式学习教程

    深入浅出的javascript的正则表达式学习教程 阅读目录 了解正则表达式的方法 了解正则中的普通字符 了解正则中的方括号[]的含义 理解javascript中的元字符 RegExp特殊字符中的需要 ...

  7. Sql导出数据报错-->SQL Server 阻止了对组件 'Ad Hoc Distributed Queries' 的 STATEMENT'OpenRowset/OpenDatasource' 的访问

    SQL Server 阻止了对组件 'Ad Hoc Distributed Queries' 的 STATEMENT'OpenRowset/OpenDatasource' 的访问,因为此组件已作为此服 ...

  8. [译]Mongoose指南 - Document

    更新 有几种方式更新document. 先看一下传统的更新方法 Tank.findById(id, function(err, tank){ if(err) return handleError(er ...

  9. 【Solr】索引库查询界面详解

    目录 索引库查询界面详解 回到顶部 索引库查询界面详解 q:主查询条件.完全支持lucene语法.还进行了扩展. fq:过滤查询.是在主查询条件查询结果的基础上进行过滤.例如:product_pric ...

  10. Entity Framework浅析

    1.Entity Framework简介 http://www.cnblogs.com/aehyok/p/3315991.html 2.Entity Framework DBFirst尝试http:/ ...