社区讨论
诡异的被卡
P2680[NOIP 2015 提高组] 运输计划参与者 2已保存回复 9
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 9 条
- 当前快照
- 1 份
- 快照标识符
- @mi6llm7g
- 此快照首次捕获于
- 2025/11/20 06:52 4 个月前
- 此快照最后确认于
- 2025/11/20 06:52 4 个月前
用二分,树上差分,倍增lca搞的
除了13个点以外都跑的很快 但是本地测试第13个点 2分钟仍然跑不出来
看了性能分析,发现大部分时间浪费在dfs上,但不是最多只有边数乘2的复杂度吗
所以是怎么被卡了?
求各位大佬指教
CPP#include<cstdio>
#include<cstring>
#define MAXN 500000
#define MAXE 500000
#define MAXP 500000
#define MAXLOG 16
int n,m;
inline char nc(){
static char buf[100000],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
template <typename T>
inline void Read(T &x){
x=0;int p=1;char c=nc();
for(;!('0'<=c&&c<='9');c=nc());
for(;'0'<=c&&c<='9';c=nc()) x=x*10+c-'0';
}
struct Edge{
int v,w,nxt;
Edge(){}
Edge(int _v,int _w,int _nxt):v(_v),w(_w),nxt(_nxt){}
}E[MAXE+10];int nE,head[MAXE+10],node[MAXN+10],nodeIndex;
inline void Link(int u,int v,int w){
E[nE]=Edge(v,w,head[u]);head[u]=nE++;
E[nE]=Edge(u,w,head[v]);head[v]=nE++;
}
int dep[MAXN+10],pfa[MAXN+10][MAXLOG],dis[MAXN+10],len[MAXN+10],cnt[MAXN+10];
int stack[MAXN+10],top;
inline int haha(){
return 0;
}
void dfs(int u){
stack[++top]=u;
while(top){
u=stack[top--];node[++nodeIndex]=u;
for(int j=1;j<=MAXLOG&&(1<<j)<=dep[u];j++)
pfa[u][j]=pfa[pfa[u][j-1]][j-1];
for(int i=head[u],v=E[i].v,k;i!=-1;i=E[i].nxt,v=E[i].v) if(pfa[u][0]!=v){
pfa[v][0]=u;dep[v]=dep[u]+1;
dis[v]=dis[u]+E[i].w;len[v]=E[i].w;
stack[++top]=v;
}
}
}
int q[MAXN+10],front,tail;
struct Plan{
int u,v,lca,dis;
Plan(){}
Plan(int _u,int _v,int _lca,int _dis):u(_u),v(_v),lca(_lca),dis(_dis){}
}P[MAXP+10];int nP;
int lca(int u,int v){
if(dep[u]<dep[v]){int t=u;u=v;v=t;}
int d=dep[u]-dep[v];
for(int i=0;(1<<i)<=d;i++) if(d&(1<<i)) u=pfa[u][i];
if(u==v) return u;
for(int i=MAXLOG-1;i>=0;i--)
if(pfa[u][i]!=pfa[v][i]) u=pfa[u][i],v=pfa[v][i];
return pfa[u][0];
}
bool Check(int val){
memset(cnt,0,sizeof(cnt));
int flag=0,limit=0;
for(int i=1;i<=nP;i++)if(P[i].dis>val){
cnt[P[i].u]++,cnt[P[i].v]++,cnt[P[i].lca]-=2;
if(limit<P[i].dis-val) limit=P[i].dis-val;
flag++;
}
if(!flag) return true;
for (int i=n;i>1;i--) cnt[pfa[node[i]][0]]+=cnt[node[i]];
for (int i=2;i<=n;i++)
if(len[i]>=limit&&cnt[i]==flag) return true;
return false;
}
int main(){
memset(head,-1,sizeof(head));
int l=0,r=0,mid,ans=0;
int maxlen=0,maxdis=0;
scanf("%d%d",&n,&m);
for(int i=1,x,y,z;i<n;i++){
Read(x);Read(y);Read(z);
Link(x,y,z);
if(z>maxlen) maxlen=z;
}
dfs(1);
for(int i=1,t,x,y;i<=m;i++){
Read(x);Read(y);
t=lca(x,y);
P[++nP]=Plan(x,y,t,dis[x]+dis[y]-(dis[t]<<1));
if(maxdis<P[i].dis) maxdis=P[i].dis;
}
l=maxdis-maxlen;r=maxdis;
while(l<=r){
mid=(l+r)>>1;
if(Check(mid)) ans=mid,r=mid-1;
else l=mid+1;
}
printf("%d\n",ans);
return 0;
}
回复
共 9 条回复,欢迎继续交流。
正在加载回复...