车站分级(加强版)
10.11
思路:
基本方法就是等级高的车站向等级低的车站连边,最后跑拓扑序的最长路就是ans。
线段树优化建边的拓扑排序(线段树的神奇应用)。
先是建虚点优化,边数优化为2*n,但是发现建边的复杂度是nm,考虑线段树优化。
注意到经停站把车站序列划分成了多个区间,每个区间对应O(log)个线段树上的节点,因此连边时可以把边数由O(nm)优化到O(m*log(n))。线段树中的上下层节点先连好边,区间整体连边的时候直接把线段树上零散的块连在虚点上即可。具体细节可以参考代码。
#include <cstdio>
#include <queue>
#include <algorithm>
#define N 400010
using namespace std;
struct Edge{
int to, nxt;
}ed[N * 20];
queue <int> q;
struct node{
int id;
node *ls, *rs;
}pool[N * 20], *tail = pool, *root;
int n, m, idc=