[문제 풀이] [LG - P3573] [POI 2014] RAJ - Plaly
26554 단어 해제데이터 구조 (DS)DAG
o r d u ord 로u ordu 는 노드 u u 의 토폴로지 순 서 를 나타 낸다.
한 노드 u u u 를 삭제 한 후에 우 리 는 노드 를 토폴로지 순서에 따라 두 부분 으로 나 누 었 다. A, B A, B. 그 중에서 A A 의 노드 의 토폴로지 순 서 는 o r d u ord 보다 작다.u ordu 의, B B B 중 노드 의 토폴로지 순 서 는 모두 o r d u ord 보다 크다.u ordu 의.
그러면 답 은 분명히 세 가지 상황 만 선택 할 수 있다.
지금 우 리 는 u u 를 삭제 하 는 상황 을 통계 한 후에 정 보 를 u 를 삭제 할 때 까지 업데이트 할 수 있다. ( o r d u ′ = o r d u + 1 ) u'~(ord_{u'}=ord_{u}+1) u′ (ordu ′ = ordu + 1) 의 경우.이 일 을 완성 하기 위해 서 우 리 는 삭제 할 수 있 는 더미 가 필요 하 다.
처음에 모든 노드 는 B B B 에 있 었 다. 즉, 모든 f (u) f (u) f (u) 를 쌓 아 올 렸 다.이어서 우 리 는 토폴로지 순서에 따라 어 릴 때 부터 어른 이 될 때 까지 노드 u u 의 관련 정 보 를 삭제 한 다음 에 u u 를 A A A 에 넣 는 것 을 고려 했다.
우선 u u 의 정 보 를 삭제 합 니 다.f (u) f (u) f (u) 를 삭제 하고 경과 (v, u) 를 삭제 합 니 다. ( v ∈ A ) (v,u)~(v\in A) (v,u) (v * 8712 ° A) 의 가장 긴 길 이면 됩 니 다 (안개).
이 어 모든 u u 의 정 보 를 추가 하고 먼저 g (u) g (u) g (u) 를 추가 한 다음 에 경과 (u, v) 를 추가 합 니 다. ( v ∈ B ) (u,v)~(v\in B) (u,v) (v * 8712 ° B) 의 가장 긴 길.
그러면 최종 코드 는 다음 과 같다.
#include
using namespace std;
const int maxn = 5e5 + 5, INF = 1e9;
int read_int() {
int t = 0; char ch = getchar();
while (ch < '0' || ch > '9') ch = getchar();
while ('0' <= ch && ch <= '9')
t = (t << 3) + (t << 1) + ch - '0',
ch = getchar();
return t;
}
int n;
struct Graph {
struct Edge {
int v, nex;
Edge(int v = 0, int nex = 0) : v(v), nex(nex) {
}
} E[maxn << 1];
int hd[maxn], deg[maxn], tote;
void addedge(int u, int v) {
E[++tote] = Edge(v, hd[u]), hd[u] = tote, deg[v]++;
}
int ls[maxn], ls_sz, f[maxn];
queue<int> q;
void topo() {
for (int i = 1; i <= n; i++) if (!deg[i]) q.push(i);
while (!q.empty()) {
int u = q.front(); q.pop(), ls[++ls_sz] = u;
for (int i = hd[u]; i; i = E[i].nex) {
int v = E[i].v;
deg[v]--;
if (!deg[v]) q.push(v);
}
}
for (int p = n; p >= 1; p--) {
int u = ls[p];
for (int i = hd[u]; i; i = E[i].nex)
f[u] = max(f[u], f[E[i].v] + 1);
}
}
} G, rG;
struct RbHeap {
priority_queue<int> q, del_q;
void push(int val) {
q.push(val); }
void pop(int val) {
del_q.push(val); }
int top() {
while (del_q.size() && q.top() == del_q.top()) q.pop(), del_q.pop();
return (q.size() ? q.top() : -INF);
}
} hp;
int main() {
int m; n = read_int(), m = read_int();
for (int i = 1; i <= m; i++) {
int u = read_int(), v = read_int();
G.addedge(u, v), rG.addedge(v, u);
}
G.topo(), rG.topo();
int ans1, ans2;
for (int i = 1; i <= n; i++) hp.push(G.f[i]);
ans2 = hp.top();
for (int p = 1; p <= n; p++) {
int u = G.ls[p]; hp.pop(G.f[u]);
for (int i = rG.hd[u]; i; i = rG.E[i].nex) {
int v = rG.E[i].v;
hp.pop(rG.f[v] + 1 + G.f[u]);
}
int val = hp.top();
if (val < ans2) ans1 = u, ans2 = val;
hp.push(rG.f[u]);
for (int i = G.hd[u]; i; i = G.E[i].nex) {
int v = G.E[i].v;
hp.push(rG.f[u] + 1 + G.f[v]);
}
}
printf("%d %d
", ans1, ans2);
return 0;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
LeetCode - 503. 다음 더 큰 요소 II (Next Greater Element II) [중간] - 분석 및 코드 (Java)순환 배열 (마지막 요소 의 다음 요 소 는 배열 의 첫 번 째 요소) 을 지정 하고 모든 요소 의 다음 요 소 를 출력 합 니 다.숫자 x 의 다음 더 큰 요 소 는 배열 에 따라 순 서 를 옮 겨 다 니 는 것 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.