1. 程式人生 > >車站分級 (線段樹優化建邊 拓撲序最長路)

車站分級 (線段樹優化建邊 拓撲序最長路)

車站分級(加強版)

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=0, tot=0, ans=0; int head[N], a[N], mrk[N], re[N], dis[N], in[N]; void adde(int u, int
v){ in[v]++; ed[++idc].to = v; ed[idc].nxt = head[u]; head[u] = idc; } node *build(int lf, int rg){ node* nd = ++tail; nd->id = ++tot; if(lf == rg){ re[lf] = nd->id; mrk[nd->id] = 1;//只有最底層的是實點,計入總長 nd->ls = nd->rs = 0; return
nd; } int mid = (lf + rg) >> 1; nd->ls = build(lf, mid); nd->rs = build(mid+1, rg); adde(nd->ls->id, nd->id);//虛點 adde(nd->rs->id, nd->id); return nd; } void modify(node *nd, int lf, int rg, int L, int R, int pos){ if(L<=lf && rg<=R){ adde(nd->id, pos); return ; } int mid = (lf + rg) >> 1; if(L <= mid) modify(nd->ls, lf, mid, L, R, pos); if(R > mid) modify(nd->rs, mid+1, rg, L, R, pos); } void solve(){//按照拓撲序跑一個最長路 for(int i=1; i<=tot+m; i++) if( !in[i] ){ q.push(i); if( mrk[i] ) dis[i] = 1; else dis[i] = 0; } while( !q.empty() ){ int u = q.front(); q.pop(); for(int i=head[u]; i; i=ed[i].nxt){ int v = ed[i].to; in[v]--; if( !in[v] ){ if( mrk[v] ) dis[v] = max(dis[v], dis[u] + 1); else dis[v] = max(dis[v], dis[u]); q.push(v); } } } } int main(){ //freopen("c.in", "r", stdin); //freopen("c.out", "w", stdout); scanf("%d%d", &n, &m); root = build(1, n); for(int i=1; i<=m; i++){ int t; scanf("%d",&t); for(int k=1; k<=t; k++){ scanf("%d", &a[k]);//線段樹中一共有tot個點 adde(tot+i, re[a[k]]);//tot+i表示第i條路徑的虛點 re是線上段樹中的pos } for(int k=2; k<=t; k++){ int R = a[k] - 1, L = a[k-1] + 1; if(L <= R) modify(root, 1, n, L, R, tot+i);//這個區間中所有的車站向虛點連邊 } } solve(); for(int i=1; i<=n; i++) ans = max(ans, dis[i]); printf("%d\n", ans); return 0; }

相關推薦

車站分級 線段優化

車站分級(加強版) 10.11 思路: 基本方法就是等級高的車站向等級低的車站連邊,最後跑拓撲序的最長路就是ans。 線段樹優化建邊的拓撲排序(線段樹的神奇應用)。 先是建虛點優化,邊數優化為2*n,但是發現建邊的複雜度是nm,考慮線段樹優化。

bzoj4383 [POI2015]Pustynia線段優化圖+dp

首先我們有樸素的想法,直接建圖拓撲序,倒著dp求每個點的最小值即可。 然而這樣建邊可能是O(n2)的 我們考慮對於一條資訊,我們新建一個節點p,大於的點我們向p連一條邊權為1的邊,小於的點p向它連一條邊權為0的邊。這樣就好多了,然而最壞還是O(n2)的囧

[bzoj5017][Snoi2017]炸彈 tarjan縮點+線段優化圖+

isp stream 現在 aps data fin zoj tput gre 5017: [Snoi2017]炸彈 Time Limit: 30 Sec Memory Limit: 512 MBSubmit: 608 Solved: 190[Submit][Stat

CF786B Legacy線段優化

好想 sin flag date ide init 技術 out nbsp 題意 有n個點,q個詢問,每次詢問有一種操作。操作1:u→[l,r](即u到l,l+1,l+2,...,r距離均為w)的距離為w;操作2:[l,r]→u的距離為w;操作3:u到v的距離為w;求起點到

787D 線段優化圖+短路

Legacy Rick and his co-workers have made a new radioactive formula and a lot of bad guys are after them. So Rick wants to give his lega

圖論訓練 車站分級 [資料結構優化][排序]

NOIP普及組原題瘋狂加難度的hard版 車站分級(c.cpp,0.5s, 256MB) 【描述】 一條單向的鐵路線上,依次有編號為 1, 2, …, n 的 n 個火車站。每個火車站都有一個級別,最低為 1 級。現有若干趟車次在這條線路上行駛,每一趟都滿

【bzoj 3073】Journeys線段優化

傳送門biu~ 線段樹的每個節點代表一個區間,建兩棵線段樹。 出線段樹每個點向父節點連邊0,表示如果能從這個區間出發也就可以從父區間出發。入線段樹每個點向子節點連邊0,表示如果能到達這個區間也就可以到達子區間。 入線段樹每個點向出線段樹的平行結點連邊0,

[bzoj3073][Pa2011]Journeys 線段優化短路

#include <bits/stdc++.h> #define pa pair<int,int> using namespace std; const int N = 30000005; int n, m, S, cnt, vir, last[5000000], dis[500000

洛谷3783 SDOI2017 天才黑客短路+虛+轉點+線段優化

題目連結 成功又一次自閉了 怕不是豬國殺之後最自閉的一次 一看到最短路徑。 我們就能推測這應該是個最短路題 現在考慮怎麼建圖 根據題目的意思,我們可以發現,在本題中,邊與邊之間存在一些轉換關係,但是點與點之間並不存在。 那麼我們考慮 邊轉點,點轉邊。 每一條邊拆成

NOIP 普及組 車站分級 [排序][線段優化][虛點優化]

一條單向的鐵路線上,依次有編號為1, 2, &hellip;, n的n個火車站。每個火車站都有一個級別,最低為1級。現有若干趟車次在這條線路上行駛,每一趟都滿足如下要求:如果這趟車次停靠了火車站x,則始發站、終點站之間所有級別大於等於火車站x的都必須停靠。(注意:起始站和終點站自然也算作事先已知需要

【bzoj4276】[ONTAK2015]Bajtman i Okr?g?y Robin 線段優化圖+費用流

har brush while inf uil mes queue eof div 題目描述 有n個強盜,其中第i個強盜會在[a[i],a[i]+1],[a[i]+1,a[i]+2],...,[b[i]-1,b[i]]這麽多段長度為1時間中選出一個時間進行搶劫,並計劃搶走

【BZOJ3681】Arietta 鏈剖分+可持久化線段優化圖+網絡流

des 持久化 -s 過程 void 但是 陽光 建圖 == 【BZOJ3681】Arietta Description Arietta 的命運與她的妹妹不同,在她的妹妹已經走進學院的時候,她仍然留在山村中。但是她從未停止過和戀人 Velding 的書信往來。一天,

Wannafly挑戰賽2 C.Butterfly線段優化枚舉

bit push har char s href max pan 線段樹 ans 題目鏈接 C.Butterfly 令$fd[i][j]$為以$s[i][j]$為起點開始往下走最大連續的‘X’個數 令$fl[i][j]$為以$s[i][j]$為

降臨線段優化dp

main spa space odi pri line 除了 發現 獲得 降臨 選定點i會有代價\(c_i\),如果一個區間j內的點全被選擇,就可以獲得回報\(p_j\)。點數和區間個數\(<1e5\)。 還以為是線段樹優化網絡流(50萬個點200萬條邊看上去很可

題解:CF115E線段優化dp

定義 可能 bit tput space nbsp sans odi bsp 題目描述 你是一個賽車比賽的組織者,想在線性王國中安排一些比賽。 線性王國有n條連續的從左到右的道路。道路從左到右依次編號為從1到n,因此道路按照升序排列。在這些道路上可能會有幾場比賽,每一場

CF-833B The Bakery線段優化Dp

imu ger another art 區間 produce let span start Some time ago Slastyona the Sweetmaid decided to open her own bakery! She bought r

Codeforces 787D. Legacy 線段優化圖+短路

self memset site cti worker for each down end rap output standard output Rick and his co-workers have made a new radioactive formula

BZOJ5017 [SNOI2017]炸彈 - 線段優化圖+Tarjan

amp col build stx mod ide update 有向圖 style Solution 一個點向一個區間內的所有點連邊, 可以用線段樹優化建圖來優化 : 前置技能傳送門 然後就得到一個有向圖, 一個聯通塊內的炸彈可以互相引爆, 所以進行縮點變成$DAG$

CF786B Legacy && 線段優化

線段樹優化連邊 要求點 \(x\) 向區間 \([L, R]\) 連邊, 一次的複雜度上限為 \(O(n)\) 然後弄成線段樹的結構 先父子連邊邊權為 \(0\) 這樣連邊就只需要連父親就可以等效於連了區間內每個點 空間複雜度為線段樹大小, 一次區間連邊時間複雜度為 \(O(\log n)\) 這是連入邊

【網路流+線段優化圖】CF793G Oleg and chess

【題目】 原題地址 有一個 n × n