[NOIP2015提高組]運輸計劃

題目:BZOJ4326、洛谷P2680、Vijos P1983、UOJ#150、codevs4632、codevs5440。

題目大意:有一棵帶權樹,有一些運輸計劃,第i個運輸計劃從ai到bi,耗時為ai到bi的距離,所有運輸計劃一起開始。現在可以把一條邊權變成0,求最終運輸計劃最短要多少時間。

解題思路:標算是樹剖,然而我并不會……

我的方法是LCA+二分+樹上差分。

首先LCA,求出每個運輸計劃的長度,可一遍dfs求出每個節點到根的距離dist,則a到b的長度為dist[a]+dist[b]-(dist[lca(a,b)]<<1)。

接著二分答案,然后判斷答案可行性。

對于每一個答案,我們要找的是所有長度大于當前答案的運輸計劃的公共邊,因為只有所有長度大于當前答案的運輸計劃全部變成小于等于當前答案,當前答案才可行。

用樹上差分(不懂請百度)。我們用s[i]記錄i到它父親這條邊有多少計劃經過。

對于每個運輸計劃,如果長度大于當前答案,我們給s[a]+1,s[b]+1,s[lca(a,b)]-2,因為我們要統計的是邊,所以對于兩個點,lca(a,b)對應的邊實際是沒有走到的,所以-2。

差分完后判斷答案可行性即可。

我用倍增時間復雜度為$O(m\log_2 n+(n+m)\log_2 len)$,len為運輸計劃的最大長度。

但常數巨大,1s很容易被卡,因此有些地方還過不掉。例如我在UOJ上就被卡97。但在時限較寬或數據較弱的地方還是能AC的。

C++ Code:

%:pragma GCC optimize(2)
#include<cstdio>
#include<cctype>
#include<cstring>
using namespace std;
char buf[10700005];
int bufpos,n,m,head[300001],deep[300001],p[300001][21],dist[300001],s[300001],fa_edge[300001],mx,now;
struct edge{int to,dis,nxt;
}e[600003];
struct que{int a,b,len,LCA;
}f[300001];
inline int max(int a,int b){return(a>b)?a:b;}
inline int readint(){char c=buf[bufpos++];for(;!isdigit(c);c=buf[bufpos++]);int p=0;for(;isdigit(c);c=buf[bufpos++])p=(p<<3)+(p<<1)+(c^'0');return p;
}
void dfs(int s){for(int i=head[s];i;i=e[i].nxt)if(!deep[e[i].to]){fa_edge[e[i].to]=i;deep[e[i].to]=deep[s]+1;p[e[i].to][0]=s;dist[e[i].to]=dist[s]+e[i].dis;dfs(e[i].to);}
}
int lca(int x,int y){if(deep[x]<deep[y])x^=y^=x^=y;int i;for(i=0;(1<<i)<=deep[x];++i);--i;for(int j=i;j>-1;--j)if(deep[p[x][j]]>=deep[y])x=p[x][j];if(x==y)return x;for(int j=i;j>-1;--j)if(p[x][j]!=-1&&p[x][j]!=p[y][j])x=p[x][j],y=p[y][j];return p[x][0];
}
void updata(int now){for(int i=head[now];i;i=e[i].nxt)if(deep[now]<deep[e[i].to]){updata(e[i].to);s[now]+=s[e[i].to];}
}
bool ok(int ans){memset(s,0,sizeof s);int gz=0;for(int i=1;i<=n;++i)if(f[i].len>ans){++gz;++s[f[i].a];++s[f[i].b];s[f[i].LCA]-=2;}updata(1);for(int i=1;i<=m;++i)if(s[i]==gz&&mx-ans<=e[fa_edge[i]].dis)return true;return false;
}
int main(){buf[fread(buf,1,10700000,stdin)]=bufpos=0;m=readint(),n=readint();for(int i=1;i<m;++i){int from=readint(),to=readint(),dis=readint();now=i<<1;e[now-1]=(edge){to,dis,head[from]};head[from]=now-1;e[now]=(edge){from,dis,head[to]};head[to]=now;}memset(p,-1,sizeof p);dist[1]=0;deep[1]=1;dfs(1);for(int j=1;(1<<j)<=m;++j)for(int i=1;i<=m;++i)if(p[i][j-1]!=-1)p[i][j]=p[p[i][j-1]][j-1];int l=0,r=0,mid;for(int i=1;i<=n;++i){f[i].a=readint();f[i].b=readint();f[i].LCA=lca(f[i].a,f[i].b);r=max(r,f[i].len=dist[f[i].a]+dist[f[i].b]-(dist[f[i].LCA]<<1));}mx=r;++r;while(l<r){mid=l+r>>1;if(ok(mid))r=mid;elsel=mid+1;}printf("%d\n",r);return 0;
}

倍增時間復雜度比較高,我改成用Tarjan求LCA,速度瞬間變快,在UOJ上成功卡了過去。不過codevs4632仍然被卡。

以下為Tarjan代碼。

C++ Code:

%:pragma GCC optimize(2)
#include<cstdio>
#include<cctype>
#include<cstring>
using namespace std;
char buf[10700005];
int bufpos,n,m,head[300001],deep[300001],dist[300001],s[300001],fa_edge[300001],mx,now,headq[300001],nq=0;
bool vis[300001];
int fa[300001];
struct edge{int to,dis,nxt;
}e[600003];
struct que{int a,b,len,LCA;
}f[300001];
struct Query{int same,nxt,to,num;bool flag;
}q[600003];
int find(int x){return(fa[x]==x)?x:(fa[x]=find(fa[x]));}
inline int max(int a,int b){return(a>b)?a:b;}
inline int readint(){char c=buf[bufpos++];for(;!isdigit(c);c=buf[bufpos++]);int p=0;for(;isdigit(c);c=buf[bufpos++])p=(p<<3)+(p<<1)+(c^'0');return p;
}
void dfs(int s){for(int i=head[s];i;i=e[i].nxt)if(!deep[e[i].to]){fa_edge[e[i].to]=i;deep[e[i].to]=deep[s]+1;dist[e[i].to]=dist[s]+e[i].dis;dfs(e[i].to);}
}
void tarjan(int root){for(int i=head[root];i;i=e[i].nxt)if(deep[root]<deep[e[i].to]){tarjan(e[i].to);fa[e[i].to]=root;vis[e[i].to]=true;}for(int i=headq[root];i;i=q[i].nxt)if(vis[q[i].to]&&!q[i].flag){q[i].flag=q[q[i].same].flag=true;f[q[i].num].LCA=find(q[i].to);}
}
void updata(int now){for(int i=head[now];i;i=e[i].nxt)if(deep[now]<deep[e[i].to]){updata(e[i].to);s[now]+=s[e[i].to];}
}
bool ok(int ans){memset(s,0,sizeof s);int gz=0;for(int i=1;i<=n;++i)if(f[i].len>ans){++gz;++s[f[i].a];++s[f[i].b];s[f[i].LCA]-=2;}updata(1);for(int i=1;i<=m;++i)if(s[i]==gz&&mx-ans<=e[fa_edge[i]].dis)return true;return false;
}
int main(){buf[fread(buf,1,10700000,stdin)]=bufpos=0;m=readint(),n=readint();for(int i=1;i<m;++i){int from=readint(),to=readint(),dis=readint();now=i<<1;e[now-1]=(edge){to,dis,head[from]};head[from]=now-1;e[now]=(edge){from,dis,head[to]};head[to]=now;fa[i]=i;}fa[m]=m;deep[1]=1;dfs(1);int l=0,r=0,mid;for(int i=1;i<=n;++i){f[i].a=readint();f[i].b=readint();int& x=f[i].a,&y=f[i].b;q[++nq].to=y;q[nq].same=nq+1;q[nq].num=i;q[nq].nxt=headq[x];headq[x]=nq;q[++nq].to=x;q[nq].same=nq-1;q[nq].num=i;q[nq].nxt=headq[y];headq[y]=nq;if(x==y)q[nq].flag=q[nq-1].flag=true,f[i].LCA=x;}tarjan(1);for(int i=1;i<=n;++i)r=max(r,f[i].len=dist[f[i].a]+dist[f[i].b]-(dist[f[i].LCA]<<1));mx=r;++r;while(l<r){mid=l+r>>1;if(ok(mid))r=mid;elsel=mid+1;}printf("%d\n",r);return 0;
}

?

轉載于:https://www.cnblogs.com/Mrsrz/p/7635580.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/282221.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/282221.shtml
英文地址,請注明出處:http://en.pswp.cn/news/282221.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

對象存儲OSS服務

一、oss是什么 阿里云對象存儲服務&#xff08;Object Storage Service&#xff0c;簡稱OSS&#xff09;為您提供基于網絡的數據存取服務。使用OSS&#xff0c;您可以通過網絡隨時存儲和調用包括文本、圖片、音頻和視頻等在內的各種非結構化數據文件。 阿里云OSS將數據文件以…

《Access 2007開發指南(修訂版)》一一1.5 什么是數據庫對象

本節書摘來自異步社區出版社《Access 2007開發指南(修訂版)》一書中的第1章&#xff0c;第1.5節&#xff0c;作者&#xff1a; 【美】Alison Balter&#xff0c;更多章節內容可以訪問云棲社區“異步社區”公眾號查看。 1.5 什么是數據庫對象 Access 2007開發指南(修訂版)正如前…

ETL工具kettle的組件--生成記錄

今天介紹下kettle的一個比較實用的組件——生成記錄&#xff1b;當我們想將一部分文本數據變成數據行&#xff0c;每個字段作為一個數據行的一個列&#xff0c;那么我們可以利用這個組件&#xff1b;它的位置在雙擊點開根據自己的實際需要進行設置當設置后&#xff0c;可以點擊…

Linux學習筆記一

linux  kernel lib module shell tools ls -la&#xff1a; 顯示所有文件包括隱藏文件  cat /proc/cpuinfo&#xff1a; 顯示cpu信息 man man  /string&#xff1a; 向上搜索string字符串 繼續按下小寫n向上搜索  ?string&#xff1a; 向下搜索string字符串 繼續按下大…

PHP中路由和rewrite的使用

一、場景介紹&#xff1a; 1、簡化url地址&#xff0c;方便大家記憶 2、有利于搜索引擎優化 3、安全&#xff08;讓用戶看不出網站的目錄結構&#xff09; 舉例&#xff1a;比如我這里將main控制器中的bb方法路由到kk&#xff0c;這樣&#xff0c;我們a標簽請求跳轉到cp.xi…

《NoSQL權威指南》導讀

引言 NoSQL權威指南“沒有什么會比引入新秩序更難&#xff0c;因為創新者必須要面對那些在舊環境中已經做得很好的對手&#xff0c;以及那些在新環境中做得很好的冷漠者。” ——Niccolo Machiavelli [1] 在過去的幾十年&#xff0c;我已經通過Elsevier/Morgan Kaufmann出版社出…

zookeeper的單實例和偽集群部署

原文鏈接: http://gudaoyufu.com/?p1395 zookeeper工作方式 ZooKeeper 是一個開源的分布式協調服務&#xff0c;由雅虎創建&#xff0c;是 Google Chubby 的開源實現。 分布式應用程序可以基于 ZooKeeper 實現諸如數據發布/訂閱、負載均衡、命名服務、分布式協 調/通知、集群管…

PHP開發常見功能實現流程

一、pc端網站登錄 1、獲取并過濾用戶提交的用戶名和密碼以及驗證碼 2、驗證用戶提交驗證碼和session中的驗證碼是否一致 3、驗證用戶名是否存在 4、根據用戶名獲取密碼&#xff0c;并校驗密碼是否一致 5、密碼一致&#xff0c;則登錄成功&#xff0c;跳轉到對應的首頁 圖示…

七牛直播云服務技術揭秘

以下根據七牛云首席布道師何李石現場演講內容整理。 直播模型及其實現 一個通用的直播模型一般包括三個模塊&#xff1a;主播方、服務器端和播放端。 首先是主播方&#xff0c;它是產生視頻流的源頭&#xff0c;由一系列流程組成&#xff1a; 第一&#xff0c;通過一定的設備來…

golang 標準庫間依賴的可視化展示

簡介 國慶看完 << Go 語言圣經 >>,總想做點什么,來加深下印象.以可視化的方式展示 golang 標準庫之間的依賴,可能是一個比較好的切入點.做之前,簡單搜了下相關的內容,網上也要討論,但是沒有發現直接能拿過來用的.標準庫之間,是必然存在依賴關系的,不同庫被依賴的程…

Amazon Alexa 新里程碑: 50000 個功能、 20000 種設備、 3500 個品牌

幾個月過去&#xff0c;Alexa的設備連接量、活躍度等各項數據又攀升了。昨日&#xff0c;亞馬遜智慧家庭副總裁DanielRausch在IFA大會上公布了Alexa的各項數據&#xff1a;全球范圍內&#xff0c;Alexa已經擁有50000個功能&#xff0c;與20000種設備相容&#xff0c;并與超過35…

C# 計算耗時的三種方法

概述計算一段程序的耗時是我們在編程中很常見的用法&#xff0c;那這節內容就通過實例的方式來演示幾種常用的統計耗時的方法.方法一&#xff1a;stopwatchstatic void Main(string[] args){Stopwatch sw new Stopwatch();sw.Start();Thread.Sleep(999);sw.Stop();Console.Wri…

《HTML5 2D游戲編程核心技術》——第1章,第1.3節特別功能

本節書摘來自華章出版社《HTML5 2D游戲編程核心技術》一書中的第1章&#xff0c;第1.3節特別功能&#xff0c;作者&#xff3b;美&#xff3d; 戴維吉爾里&#xff0c;更多章節內容可以訪問云棲社區“華章計算機”公眾號查看。 1.3 特別功能 Snail Bait游戲有3個特別的功能&a…

XunSearch的安裝和加入服務器開機腳本以及將目錄寫入系統變量

一、安裝xunserach 1、cd ~ 2、wget http://www.xunsearch.com/download/xunsearch-full-latest.tar.bz2 #下載最新xunsearch包 3、tar -xjf xunsearch-full-latest.tar.bz2 #解壓xunsearch包 4、cd xunsearch-full-1.4.11/ #進入xunsearch包目錄 5、sh setup.sh #執…

dubbo源碼解析-zookeeper創建節點

前言 在之前dubbo源碼解析-本地暴露中的前言部分提到了兩道高頻的面試題,其中一道dubbo中zookeeper做注冊中心,如果注冊中心集群都掛掉,那發布者和訂閱者還能通信嗎?在上周的dubbo源碼解析-zookeeper連接中已經講到,這周解析的是另一道,即服務提供者能實現失效踢出是根據什么原…

配置mysql為主主復制步驟

mysql版本&#xff1a;mysql-5.6.24-solaris10-sparc-64bit.tar 操作系統&#xff1a;solaris 11g u10 操作用戶&#xff1a;使用非root進行操作安裝&#xff0c;a路服務器ip地址為192.168.1.1 b路ip地址為192.168.1.2&#xff08;應改為實際ip地址&#xff09; 1&#xff0c;安…

XunSearch的使用

一、項目的配置文件 1、要想使用xunsearch&#xff0c;首先需要進行配置文件的配置。 默認目錄在app下&#xff0c;如下面的結構&#xff0c;每一個搜索項目都需要有一個ini文件進行相應的配置。 舉例&#xff1a; project.name novel project.default_charset utf-8 serv…

《VMware vSphere設計(原書第2版)》——1.1 什么是設計

本節書摘來自華章出版社《VMware vSphere設計&#xff08;原書第2版&#xff09;》一 書中的第1章&#xff0c;第1.1節&#xff0c;作者&#xff1a;[美] 福布斯格思里&#xff08;Forbes Guthrie&#xff09;斯科特羅威&#xff08;Scott Lowe&#xff09;肯德里克科爾曼&…

SqlKata - 方便好用的 Sql query builder

SqlKata查詢生成器是一個用C# 編寫的功能強大的Sql查詢生成器。它是安全的&#xff0c;與框架無關。靈感來源于可用的頂級查詢生成器&#xff0c;如Laravel Query Builder和 Knex&#xff1a;https://knexjs.org/。SqlKata有一個富有表現力的API。它遵循一個干凈的命名約定&…

編寫高質量代碼:改善Java的151個建議四(基本類型)21-30

該書籍PDF下載地址&#xff1a;http://download.csdn.net/download/muyeju/10001473 基本類型有8個&#xff1a;byte&#xff0c;short&#xff0c;int&#xff0c;char&#xff0c;long&#xff0c;double&#xff0c;float&#xff0c;boolean 21.用偶判斷&#xff0c;不用奇…