[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.
給定一個(gè) \(N\) 個(gè)點(diǎn) \(M\) 條邊的有向無(wú)環(huán)圖,每條邊長(zhǎng)度都是 \(1\)。
請(qǐng)找到一個(gè)點(diǎn),使得刪掉這個(gè)點(diǎn)后剩余的圖中的最長(zhǎng)路徑最短。
輸入
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\).
第一行包含兩個(gè)正整數(shù) \(N,M\)(\(2 \le N \le 500 000,1 \le M \le 1 000 000\)),表示點(diǎn)數(shù)、邊數(shù)。
接下來(lái) \(M\) 行每行包含兩個(gè)正整數(shù) \(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.
包含一行兩個(gè)整數(shù) \(x,y\),用一個(gè)空格隔開(kāi),\(x\) 為要?jiǎng)h去的點(diǎn),\(y\) 為刪除 \(x\) 后圖中的最長(zhǎng)路徑的長(zhǎng)度,如果有多組解請(qǐng)輸出任意一組。
輸入示例
6 5 1 3 1 4 3 6 3 4 4 5輸出示例
1 2數(shù)據(jù)規(guī)模及約定
見(jiàn)“輸入”
題解
首先建立 \(S\) 和 \(T\),\(S\) 向所有點(diǎn)連邊,所有點(diǎn)向 \(T\) 連邊,那么原圖中的最長(zhǎng)路就等于現(xiàn)在 \(S\) 到 \(T\) 的最長(zhǎng)路減 \(2\) 了。
考慮給每條邊賦權(quán)值,權(quán)值即為經(jīng)過(guò)這條邊的最長(zhǎng)路的長(zhǎng)度,這個(gè)權(quán)值顯然很好計(jì)算,正反 dp 一下就好了。
然后我們枚舉刪每個(gè)點(diǎn)之后的最長(zhǎng)路分別是多少。我們按照拓?fù)湫蛎杜e這個(gè)點(diǎn);首先將所有從 \(S\) 出發(fā)的邊的邊權(quán)加到堆中,然后將枚舉的點(diǎn) \(x\) 的入邊全都刪掉;當(dāng)枚舉的點(diǎn) \(x\) 變成 \(x'\) 時(shí),將 \(x\) 的出邊加入,\(x'\) 的入邊刪掉;這樣能保證任意時(shí)刻在堆中的路徑都是不經(jīng)過(guò)當(dāng)前的 \(x\),并且包含所有可能出現(xiàn)的最長(zhǎng)路徑。
#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; }轉(zhuǎn)載于:https://www.cnblogs.com/xiao-ju-ruo-xjr/p/8879935.html
《新程序員》:云原生和全面數(shù)字化實(shí)踐50位技術(shù)專(zhuān)家共同創(chuàng)作,文字、視頻、音頻交互閱讀總結(jié)
以上是生活随笔為你收集整理的[BZOJ3832][Poi2014]Rally的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Java的工厂模式(三)
- 下一篇: 上云、微服务化和DevOps,少走弯路的