This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include <bits/stdc++.h>
#ifndef SKY
#include "swap.h"
#endif // SKY
using namespace std;
#define N 200010
#define ll long long
#define fs first
#define sc second
#define ii pair<int,int>
#define pb push_back
const int root=2;
vector<ii>g[N];
vector<int>f[N];
vector<ii>vec[N];
int sz[N],n,m,head[N],dp[N],times,LOG,chain,in[N],pos[N],picked[N],MV[N];
ii cha[N][21],cnt[N];
struct IT_LAZY
{
int ST[N*4]={};
void init()
{
for(int i=1;i<=n*4;i++)
ST[i]=2e9;
}
void update(int id,int l,int r,int u,int v,int val)
{
if(l>v||r<u)
return;
if(l>=u&&r<=v)
{
ST[id]=min(ST[id],val);
return;
}
int mid=(l+r)/2;
update(id*2,l,mid,u,v,val);
update(id*2+1,mid+1,r,u,v,val);
}
int get(int id,int l,int r,int i)
{
if(l>i||r<i)
return 2e9;
if(l==r)
return ST[id];
int res=ST[id];
int mid=(l+r)/2;
res=min(res,get(id*2,l,mid,i));
res=min(res,get(id*2+1,mid+1,r,i));
return res;
}
void hld_update(int r,int u,int cost)
{
while(in[u]!=in[r])
{
update(1,1,n,pos[head[in[u]]],pos[u],cost);
u=cha[head[in[u]]][0].sc;
}
if(r==u)
return;
update(1,1,n,pos[MV[u]],pos[u],cost);
}
}IT_LAZY;
struct IT
{
int ST[N*4]={};
void init()
{
for(int i=1;i<=n*4;i++)
ST[i]=2e9;
}
void update(int id,int l,int r,int i,int val)
{
if(l>i||r<i)
return;
if(l==r)
{
ST[id]=val;
return;
}
int mid=(l+r)/2;
update(id*2,l,mid,i,val);
update(id*2+1,mid+1,r,i,val);
ST[id]=min(ST[id*2],ST[id*2+1]);
}
int get(int id,int l,int r,int u,int v)
{
if(l>v||r<u)
return 2e9;
if(l>=u&&r<=v)
return ST[id];
int mid=(l+r)/2;
return min(get(id*2,l,mid,u,v),get(id*2+1,mid+1,r,u,v));
}
}IT;
struct DSU
{
int lab[N];
void init()
{
memset(lab,-1,sizeof(lab));
}
int root(int u)
{
if(lab[u]<0)
return u;
return(lab[u]=root(lab[u]));
}
bool update(int u,int v)
{
if((u=root(u))==(v=root(v)))
return 0;
if(lab[u]>lab[v])
swap(u,v);
lab[u]+=lab[v];
lab[v]=u;
return 1;
}
}DSU;
struct canh
{
int u,v,w;
bool operator<(const canh&A)const
{
return w<A.w;
}
};
vector<canh>edge;
int get_min(int u,int A,int B)
{
if(f[u].size()<3)
return 2e9;
if(A>B)
swap(A,B);
if(f[u][0]!=A)
return f[u][0];
if(f[u][1]!=B)
return f[u][1];
return f[u][2];
}
void DFS(int u,int p)
{
cnt[u].fs=++times;
sz[u]=1;
for(auto v:g[u])
if(v.sc!=p)
{
cha[v.sc][0]={v.fs,u};
DFS(v.sc,u);
sz[u]+=sz[v.sc];
}
cnt[u].sc=times;
}
void hld(int u,int p)
{
in[u]=chain;
pos[u]=++times;
if(head[chain]==0)
head[chain]=u;
for(auto v:g[u])
if(v.sc!=p&&(MV[u]==0||sz[v.sc]>sz[MV[u]]))
MV[u]=v.sc;
if(MV[u]==0)
return;
hld(MV[u],u);
for(auto v:g[u])
if(v.sc!=p&&v.sc!=MV[u])
{
chain++;
hld(v.sc,u);
}
}
bool tren(int u,int v)
{
return(cnt[u].fs<=cnt[v].fs&&cnt[u].sc>=cnt[v].sc);
}
int lca(int u,int v)
{
if(tren(u,v))
return u;
if(tren(v,u))
return v;
for(int k=LOG;k>=0;k--)
if(cha[u][k].sc!=0&&!tren(cha[u][k].sc,v))
u=cha[u][k].sc;
return cha[u][0].sc;
}
int con_duoi(int r,int u)
{
for(int k=LOG;k>=0;k--)
if(cha[u][k].sc!=0&&!tren(cha[u][k].sc,r))
u=cha[u][k].sc;
return u;
}
int get_max(int r,int u)
{
if(r==u)
return 0;
int res=0;
for(int k=LOG;k>=0;k--)
if(cha[u][k].sc!=0&&!tren(cha[u][k].sc,r))
{
res=max(res,cha[u][k].fs);
u=cha[u][k].sc;
}
return max(res,cha[u][0].fs);
}
int get_2_con(int u,int A)
{
if(f[u].size()<3)
return 2e9;
if(f[u][0]==A)
return max(f[u][1],f[u][2]);
if(f[u][1]==A)
return max(f[u][0],f[u][2]);
return max(f[u][0],f[u][1]);
}
void build(int u,int p)
{
if(u!=root)
dp[u]=get_2_con(u,cha[u][0].fs);
for(auto v:g[u])
if(v.sc!=p)
{
build(v.sc,u);
dp[u]=min(dp[u],max(v.fs,dp[v.sc]));
}
}
void nguoc(int u,int p,int val)
{
for(auto v:g[u])
if(v.sc!=p)
vec[u].pb({max(v.fs,dp[v.sc]),v.sc});
sort(vec[u].begin(),vec[u].end());
for(auto v:g[u])
if(v.sc!=p)
{
if(v.sc==vec[u][0].sc)
{
nguoc(v.sc,u, max(v.fs,min((vec[u].size()<2 ? (int)2e9 : vec[u][1].fs),val)));
}else
{
nguoc(v.sc,u,max(v.fs,min(vec[u][0].fs,val)));
}
}
vec[u].clear();
for(auto v:g[u])
if(v.sc!=p&&dp[v.sc]<=1e9)
vec[u].pb({max(v.fs,dp[v.sc]),v.sc});
if(val<=1e9)
vec[u].pb({val,p});
sort(vec[u].begin(),vec[u].end());
}
void init(int NNN, int MMM,vector<int> UUU,vector<int> VVV, vector<int> WWW)
{
n=NNN;
m=MMM;
// assert(m==n-1);
for(int i=0;i<m;i++)
{
UUU[i]++;
VVV[i]++;
edge.pb({UUU[i],VVV[i],WWW[i]});
f[UUU[i]].pb(WWW[i]);
f[VVV[i]].pb(WWW[i]);
}
sort(edge.begin(),edge.end());
DSU.init();
for(int i=0;i<m;i++)
if(DSU.update(edge[i].u,edge[i].v))
{
// cout<<edge[i].u-1<<" "<<edge[i].v-1<<endl;
picked[i]=1;
g[edge[i].u].pb({edge[i].w,edge[i].v});
g[edge[i].v].pb({edge[i].w,edge[i].u});
}
for(int i=1;i<=n;i++)
sort(f[i].begin(),f[i].end());
DFS(root,0);
times=0;
hld(root,0);
LOG=log2(n);
for(int k=1;k<=LOG;k++)
for(int i=1;i<=n;i++)
cha[i][k]={max(cha[cha[i][k-1].sc][k-1].fs,cha[i][k-1].fs),cha[cha[i][k-1].sc][k-1].sc};
IT.init();
for(int i=1;i<=n;i++)
if(i!=root&&cha[i][0].sc!=root)
IT.update(1,1,n,pos[i],get_min(cha[i][0].sc,cha[i][0].fs,cha[cha[i][0].sc][0].fs));
IT_LAZY.init();
for(int i=0;i<m;i++)
if(picked[i]==0)
{
int u=edge[i].u,v=edge[i].v,r=lca(u,v),cost=max(edge[i].w,max(get_max(r,u),get_max(r,v)));
IT_LAZY.hld_update(r,u,cost);
IT_LAZY.hld_update(r,v,cost);
}
memset(dp,0x3f3f,sizeof(dp));
build(root,0);
nguoc(root,0,2e9);
// exit(0);
}
int get(int r,int u)
{
int res=2e9;
while(in[u]!=in[r])
{
res=min(res,IT.get(1,1,n,pos[head[in[u]]],pos[u]));
u=cha[head[in[u]]][0].sc;
}
if(u==r)
return res;
return min(res,IT.get(1,1,n,pos[MV[r]],pos[u]));
}
int get_cay_vl(int u,int c)
{
if(vec[u].empty())
return 2e9;
if(vec[u][0].sc==c)
{
if(vec[u].size()<2)
return 2e9;
return vec[u][1].fs;
}
return vec[u][0].fs;
}
int getMinimumFuelCapacity(int u, int v)
{
u++;
v++;
int r=lca(u,v),res=2e9;///max(get_max(r,u),get_max(r,v));
if(r==u)
swap(u,v);
// cout<<u-1<<" "<<v-1<<" "<<r-1<<" "<<con_duoi(r,u)-1<<endl;
if(u!=r)
res=min(res,get(con_duoi(r,u),u));
if(v!=r)
res=min(res,get(con_duoi(r,v),v));
// assert(v==1||u==1);
if(r==v)
{
res=min(res,get_2_con(r,cha[con_duoi(r,u)][0].fs));
res=min(res,get_2_con(u,cha[u][0].fs));
res=min(res,get_cay_vl(r,con_duoi(r,u)));
res=min(res,get_cay_vl(u,cha[u][0].sc));
}else
{
res=min(res,get_2_con(u,cha[u][0].fs));
res=min(res,get_2_con(v,cha[v][0].fs));
res=min(res,get_min(r,cha[con_duoi(r,u)][0].fs,cha[con_duoi(r,v)][0].fs));
res=min(res,get_cay_vl(u,cha[u][0].sc));
res=min(res,get_cay_vl(v,cha[v][0].sc));
}
res=min(res,IT_LAZY.get(1,1,n,pos[u]));
// cout<<res<<endl;
res=max(res,max(get_max(r,u),get_max(r,v)));
if(res<=1e9)
return res;
else return -1;
}
#ifdef SKY
int main()
{
freopen("A.inp","r",stdin);
freopen("A.out","w",stdout);
ios::sync_with_stdio(0);
cin.tie(NULL);
cout.tie(NULL);
int n,m;
cin>>n>>m;
vector<int>U(m),V(m),W(m);
for(int i=0;i<m;i++)
cin>>U[i];
for(int i=0;i<m;i++)
cin>>V[i];
for(int i=0;i<m;i++)
cin>>W[i];
init(n,m,U,V,W);
int q;
cin>>q;
while(q--)
{
int u,v;
cin>>u>>v;
cout<<getMinimumFuelCapacity(u,v)<<endl;
}
return 0;
}
#endif
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |