[BZOJ3832][Poi2014]Rally
[BZOJ3832][Poi2014]Rally
試題描述
An annual bicycle rally will soon begin in Byteburg. The bikers of Byteburg are natural long distance cyclists. Local representatives of motorcyclists, long feuding the cyclists, have decided to sabotage the event.
There are intersections in Byteburg, connected with one way streets. Strangely enough, there are no cycles in the street network - if one can ride from intersection \(U\) to intersection \(V\) , then it is definitely impossible to get from \(V\) to \(U\).
The rally's route will lead through Byteburg's streets. The motorcyclists plan to ride their blazing machines in the early morning of the rally day to one intersection and completely block it. The cyclists' association will then of course determine an alternative route but it could happen that this new route will be relatively short, and the cyclists will thus be unable to exhibit their remarkable endurance. Clearly, this is the motorcyclists' plan - they intend to block such an intersection that the longest route that does not pass through it is as short as possible.
給定一個 \(N\) 個點 \(M\) 條邊的有向無環圖,每條邊長度都是 \(1\)。
請找到一個點,使得刪掉這個點后剩余的圖中的最長路徑最短。
輸入
In the first line of the standard input, there are two integers, \(N\) and \(M\)(\(2 \le N \le 500 000,1 \le M \le 1 000 000\)), separated by a single space, that specify the number of intersections and streets in Byteburg. The intersections are numbered from \(1\) to \(N\). The lines that follow describe the street network: in the \(i+1\)-th of these lines, there are two integers, \(A_i, B_i\)(\(1 \le A_i,B_i \le N,A_i \ne B_i\)), separated by a single space, that signify that there is a one way street from the intersection no. \(A_i\) to the one no. \(B_i\).
第一行包含兩個正整數 \(N,M\)(\(2 \le N \le 500 000,1 \le M \le 1 000 000\)),表示點數、邊數。
接下來 \(M\) 行每行包含兩個正整數 \(A[i],B[i]\)(\(1 \le A[i],B[i] \le N,A[i] \ne B[i]\)),表示 \(A[i]\) 到 \(B[i]\) 有一條邊。
輸出
The first and only line of the standard output should contain two integers separated by a single space. The first of these should be the number of the intersection that the motorcyclists should block, and the second - the maximum number of streets that the cyclists can then ride along in their rally. If there are many solutions, your program can choose one of them arbitrarily.
包含一行兩個整數 \(x,y\),用一個空格隔開,\(x\) 為要刪去的點,\(y\) 為刪除 \(x\) 后圖中的最長路徑的長度,如果有多組解請輸出任意一組。
輸入示例
6 5 1 3 1 4 3 6 3 4 4 5輸出示例
1 2數據規模及約定
見“輸入”
題解
首先建立 \(S\) 和 \(T\),\(S\) 向所有點連邊,所有點向 \(T\) 連邊,那么原圖中的最長路就等于現在 \(S\) 到 \(T\) 的最長路減 \(2\) 了。
考慮給每條邊賦權值,權值即為經過這條邊的最長路的長度,這個權值顯然很好計算,正反 dp 一下就好了。
然后我們枚舉刪每個點之后的最長路分別是多少。我們按照拓撲序枚舉這個點;首先將所有從 \(S\) 出發的邊的邊權加到堆中,然后將枚舉的點 \(x\) 的入邊全都刪掉;當枚舉的點 \(x\) 變成 \(x'\) 時,將 \(x\) 的出邊加入,\(x'\) 的入邊刪掉;這樣能保證任意時刻在堆中的路徑都是不經過當前的 \(x\),并且包含所有可能出現的最長路徑。
#include <bits/stdc++.h> using namespace std; #define rep(i, s, t) for(int i = (s), mi = (t); i <= mi; i++) #define dwn(i, s, t) for(int i = (s), mi = (t); i >= mi; i--)int read() {int x = 0, f = 1; char c = getchar();while(!isdigit(c)){ if(c == '-') f = -1; c = getchar(); }while(isdigit(c)){ x = x * 10 + c - '0'; c = getchar(); }return x * f; }#define maxn 500010 #define maxm 2000010 #define oo 2147483647int n, S, T, ind[maxn]; struct Edge {int a, b, c;Edge() {}Edge(int _, int __): a(_), b(__) {} } es[maxm]; struct Graph {int m, head[maxn], nxt[maxm], to[maxm], id[maxm];void AddEdge(int a, int b, int i) {to[++m] = b; id[m] = i; nxt[m] = head[a]; head[a] = m;return ;} } G, rG;int hd, tl, Qd[maxn]; int ds[maxn], dt[maxn]; priority_queue <int> Q, delQ;int main() {n = read(); int m = read();rep(i, 1, m) {int a = read(), b = read();G.AddEdge(a, b, i); rG.AddEdge(b, a, i);es[i] = Edge(a, b);ind[b]++;}S = n + 1; T = n + 2;rep(i, 1, n) {G.AddEdge(S, i, m + i);es[m+i] = Edge(S, i);G.AddEdge(i, T, m + n + i);es[m+n+i] = Edge(i, T);rG.AddEdge(i, S, m + i);rG.AddEdge(T, i, m + n + i);ind[i]++; ind[T]++;}n += 2;hd = tl = 0;rep(i, 1, n) if(!ind[i]) Qd[++tl] = i;while(hd < tl) {int u = Qd[++hd];for(int e = G.head[u]; e; e = G.nxt[e]) if(!--ind[G.to[e]]) Qd[++tl] = G.to[e];}rep(i, 1, n) {int u = Qd[i];for(int e = G.head[u]; e; e = G.nxt[e]) ds[G.to[e]] = max(ds[G.to[e]], ds[u] + 1);}dwn(i, n, 1) {int u = Qd[i];for(int e = G.head[u]; e; e = G.nxt[e]) dt[u] = max(dt[u], dt[G.to[e]] + 1);}int cnte = m + (n - 2 << 1);rep(i, 1, cnte) es[i].c = ds[es[i].a] + 1 + dt[es[i].b]; // , printf("%d -> %d %d\n", es[i].a, es[i].b, es[i].c);for(int e = G.head[Qd[1]]; e; e = G.nxt[e]) Q.push(es[G.id[e]].c);int mn = oo, mnp;rep(i, 2, n - 1) {int u = Qd[i];for(int e = rG.head[u]; e; e = rG.nxt[e]) {delQ.push(es[rG.id[e]].c);while(!delQ.empty() && delQ.top() == Q.top()) delQ.pop(), Q.pop();}if(i > 2) {int v = Qd[i-1];for(int e = G.head[v]; e; e = G.nxt[e]) {Q.push(es[G.id[e]].c);while(!delQ.empty() && delQ.top() == Q.top()) delQ.pop(), Q.pop();}}assert(!Q.empty());if(Q.top() < mn) mn = Q.top(), mnp = u;}printf("%d %d\n", mnp, mn - 2);return 0; }轉載于:https://www.cnblogs.com/xiao-ju-ruo-xjr/p/8879935.html
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀總結
以上是生活随笔為你收集整理的[BZOJ3832][Poi2014]Rally的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: Java的工厂模式(三)
- 下一篇: 上云、微服务化和DevOps,少走弯路的
