bzoj4326: NOIP2015 運輸計劃(lca+二分)
題目傳送門
好題啊。
解法:
比較綜合。。
我一開始想:
先把所有距離求出來。
然後二分答案。
所有的路徑距離>答案 說明需要建蟲洞。
在所有大於答案的路徑中是有交集的。
那麼我們只需要在交集中找到一條邊使得所有路徑-邊權<=答案。
然後用差分咯。
sum[i]表示1到i這條邊次數都加1。
然後就差分嘛。
對於每個x和y。
1到x路徑+1
1到y路徑+1
1到lca路徑-2就行了嘛。
程式碼實現:
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<queue>
using namespace std;
struct node {int x,y,c,next;}a[2100000];int len,last[1100000];
void ins(int x,int y,int c) {len++;a[len].x=x;a[len].y=y;a[len].c=c;a[len].next=last[x];last[x]=len;}
int n,m,mn[21][610000],dfn,dep[1100000],ys[1100000],bin[21],dist[1100000],Lca[1100000],to[1100000];//ys表示與父親的邊權
void dfs(int x) {
for(int k=last[x];k;k=a[k].next) {
int y=a[k].y;
if(y!=mn[0][x]) {mn[0][y]=x;dep[y]=dep[x]+1;ys[y]=a[k].c;to[y]=to[x]+a[k].c;dfs(y);}
}
}
void work() {
bin[0]=1;for(int i=1;i<=20;i++)bin[i]=bin[i-1]*2;
for(int j=1;j<=20;j++)for(int i=1;i<=n;i++)if(dep[i]>=bin[j])mn[j][i]=mn[j-1][mn[j-1][i]];
}
int lca(int x,int y) {
if(dep[x]>dep[y])swap(x,y);
for(int i=20;i>=0;i--)if(dep[y]-dep[x]>=bin[i])y=mn[i][y];
if(x==y)return x;
for(int i=20;i>=0;i--)if(mn[i][y]!=mn[i][x]&&dep[x]>=bin[i]){x=mn[i][x];y=mn[i][y];}
return mn[0][x];
}
int xx[1100000],yy[1100000],sum[1100000];
void cf(int x) {
for(int k=last[x];k;k=a[k].next) {
int y=a[k].y;
if(y!=mn[0][x]) {cf(y);sum[x]+=sum[y];}
}
}
int main() {
scanf("%d%d",&n,&m);len=0;memset(last,0,sizeof(last));
for(int i=1;i<n;i++) {int x,y,c;scanf("%d%d%d",&x,&y,&c);ins(x,y,c);ins(y,x,c);}
mn[0][1]=0;dep[1]=0;ys[1]=0;to[1]=0;dfs(1);work();
int l=1,r=0,mid,ans=0;
for(int i=1;i<=m;i++) {
scanf("%d%d",&xx[i],&yy[i]);Lca[i]=lca(xx[i],yy[i]);
dist[i]=to[xx[i]]+to[yy[i]]-2*to[Lca[i]];r=max(r,dist[i]);
}
while(l<=r) {
mid=(l+r)/2;int mmax=0,tot=0;memset(sum,0,sizeof(sum));
for(int i=1;i<=m;i++)if(dist[i]>mid) {
tot++;mmax=max(mmax,dist[i]-mid);sum[xx[i]]++;sum[yy[i]]++;sum[Lca[i]]-=2;
}cf(1);
bool bk=false;
for(int i=1;i<=n;i++)if(sum[i]>=tot&&ys[i]>=mmax) {bk=true;break;}
if(bk==true) {r=mid-1;ans=mid;}
else l=mid+1;
}
printf("%d\n",ans);
return 0;
}
相關文章
- [NOIP2015 提高組] 運輸計劃(二分 + lca + 樹上差分)
- 貨車運輸(LCA+最大生成樹)
- 運輸計劃和處理的前提條件
- 【貪心】【二分】[NOIP2015]跳石頭
- 二分法在計算機維修中運用計算機
- 計算機網路之運輸層計算機網路
- MySQL執行計劃explain輸出列結果解析MySqlAI
- 交通運輸部:2019年交通運輸行業發展統計公報行業
- 交通運輸部:2021年10月交通運輸行業主要統計指標行業指標
- 交通運輸部:2023年交通運輸行業發展統計公報行業
- 虛擬化運維:規劃和發展戰略性 IT 計劃運維
- 遊戲運營入門——從一份運營計劃說起遊戲
- 交通運輸部:2022年11月交通運輸行業主要統計指標行業指標
- 交通運輸部:2022年5月交通運輸行業主要統計指標行業指標
- 貨車運輸
- 交通運輸部:2024年1-5月交通運輸行業主要統計指標行業指標
- 交通運輸部:2024年1-4月交通運輸行業主要統計指標行業指標
- SQL Server查詢計劃系列之——邏輯運算子與物理運算子SQLServer
- 如何運用專案管理思維制定工作計劃?專案管理
- mongodb 常見運維監控和執行計劃MongoDB運維
- 如何計劃學習新媒體運營的方向?
- 自動化運維平臺的實施計劃運維
- 從TOP100summit看產品設計和運營創新的“B”計劃和“C”計劃MIT
- 遊戲基礎知識——“運輸單位”的設計遊戲
- 計算機網路 - 運輸層 - 學習筆記計算機網路筆記
- 作業6--四則運算APP之Sprint計劃APP
- 【執行計劃】格式化EXPLAIN PLAN的輸出結果AI
- HDU 4417-Super Mario(劃分樹-二分查詢)
- [dp 小計] wqs 二分
- 運輸層協議概述協議
- 鐳速傳輸點亮“0元百日計劃”,為資料傳輸打通高速通道
- Linux 的計劃任務(運維基礎|可用於提權)Linux運維
- 前端鍍金計劃:網路傳輸之TCP/IP協議族前端TCP協議
- 計算機網路-5-10-TCP運輸連線管理計算機網路TCP
- 計劃
- 動態規劃如何輸出路徑?動態規劃
- NOIP2015子串[序列DP]
- [NOIP2015 提高組] 子串