NOIP2015運輸計畫的乙個O n 解法

2022-05-31 02:06:08 字數 1641 閱讀 9796

那麼,我們用類似提直徑的方法把這條路徑給拎出來

就會形成這樣的一棵樹。

那麼,對於一條邊,若其被改成蟲洞,最長路徑會有如下三種情況:

難道我們不用考慮經過該邊的路徑嗎??

當然不用。

我們已經是在最長路徑上改造邊了,而最長路徑是長於任何一條路徑的(廢話),那麼經過該邊的任何路徑在此邊被改造後依然短於最長路徑,故不用考慮。

至於求兩端的最長路徑,我們可以字首和字尾分別維護一下。

我們可以在每個點開個vector,對於一條路徑,我們把另一端點以及路徑的編號加到vector中。

然後,再開個vis陣列,表示這個點是否被訪問過。

在遍歷時,我們訪問所有以這一點為一端點的路徑標號\(id\)和另一端點\(y\),若另\(vis[y]=true\),就拿\(id\)的長度去更新即可。(口胡不清,這最好手動模擬一下)

額,樹剖我是當常數看的。。。

實在不行你可以tarjan離線預處理啊

**(巨醜無比):

#include#define reg register int

#define maxn 300010

using namespace std;

int n,m,head[maxn],dis[maxn],tot,maxx,bh,pre[maxn],sumfr[maxn],sumla[maxn],num[maxn],lian[maxn],ans=2e9+7;

bool mark[maxn],vis[maxn];

struct node p[maxn];

struct edge g[maxn*2];

struct que ;

vectorq[maxn];

struct s__

} shupou;

void rd(int &res)

void add(int st,int ed,int v) ;

head[st]=tot;

}void dfs(int x,int fa,int &bb)

}void dfsla(int x,int fa,int zu) );

q[p[i].ed].push_back(que );

} int st=p[bh].st,ed=p[bh].ed,lca=p[bh].lca;

while(st!=lca)mark[st]=true,st=pre[st];

while(ed!=lca)mark[ed]=true,ed=pre[ed];

mark[lca]=true;

int bb=1;

dfs(p[bh].st,0,bb);

dfsfr(p[bh].st,0,num[p[bh].st]);

memset(vis,false,sizeof(vis));

dfsla(p[bh].ed,0,num[p[bh].ed]);

for(int i=1;i<=bb;i++)

cout<

return 0;

}

noip2015 運輸計畫

公元 2044 年,人類進入了宇宙紀元。l 國有 n 個星球,還有 n 1 條雙向航道,每條航道建立在兩個星球之間,這 n 1 條航道連通了 l 國的所有星球。小 p 掌管一家物流公司,該公司有很多個運輸計畫,每個運輸計畫形如 有一艘物流飛船需要從 ui 號星球沿最快的宇航路徑飛行到 vi 號星球去...

NOIP2015 運輸計畫

題目鏈結 codevs 4632 題目大意 在一棵 n 節點樹上,有 m個運輸計畫 從ai 到 bi n,m 300000 問 把哪一條樹邊的權值變為0,可以使所有運輸計畫的最大距離最小,輸出這個最大距離的最小值。分析 0.首先要會lca和樹上差分。1.顯然,這道題要求樹上兩點之間的距離,所以要寫l...

noip 2015 運輸計畫

去題面的傳送門 題目的意思是 求將一棵樹上的任意一條邊權賦值為0時,所有航線的最長長度的最小值 想到二分答案 如何驗證?既然我們二分的答案是最長路線,也就是說,在將一條邊權賦值為0之後,所有的路線長度應該都小於等於mid。但是只能刪掉一條邊,所以這條邊是所有刪邊之前長度小於mid的路線的交邊。問題轉...