# | 제출 시각 | 아이디 | 문제 | 언어 | 결과 | 실행 시간 | 메모리 |
---|---|---|---|---|---|---|---|
899085 | Denkata | 공장들 (JOI14_factories) | C++14 | 0 ms | 0 KiB |
이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#include<bits/stdc++.h>
#include "factories.h"
#include "grader.cpp"
using namespace std;
const int maxn = 5e5+3;
int i,j,p,q,n,m,k,par[maxn],sz[maxn],tin[maxn],tout[maxn],br,l,timer,lasttime[maxn],cnt;
long long ans[maxn],raz[maxn];
vector <int> up[maxn];
///moje i set
struct Put
{
int v;
long long d;
};
bool operator<(Put a,Put b)
{
return a.v<b.v;
}
set <Put> v[maxn];
void dfs(int u,int p)
{
tin[u]=++timer;
up[u][0]=p;
for(int j=1;j<=l;j++)
{
up[u][j]=up[up[u][j-1]][j-1];
}
for(auto i:v[u])
{
int q=i.v;
if(q!=p)
{
raz[q]=raz[u]+i.d;
dfs(q,u);
}
}
//cout<<u<<" "<<p<<endl;
tout[u]=++timer;
}
bool upper(int a,int b)
{
return (tin[a]<=tin[b] && tout[a]>=tout[b]);
}
int lca(int a,int b)
{
if(upper(a,b))return a;
if(upper(b,a))return b;
for(int ii=l;ii>=0;ii--)
{
if(!upper(up[a][ii],b))
a=up[a][ii];
}
return up[a][0];
}
int find_size(int u,int p)
{
sz[u] = 1;
for(auto i:v[u])
if(i.v!=p)sz[u]+=find_size(i.v,u);
return sz[u];
}
int find_centroid(int u,int p,int N)
{
for(auto i:v[u])
if(i.v!=p && sz[i.v]>N/2)return find_centroid(i.v,u,N);
return u;
}
void centroid_decomposition(int u,int p)
{
cout<<u<<" centr "<<p<<endl;
int N = find_size(u,p);
int c = find_centroid(u,p,N);
par[c] = p;
cout<<"par of "<<c<<" is "<<p<<endl;
stack <pair <int,int>> st;
for(auto i:v[c])
{
v[i.v].erase({c,i.d});
centroid_decomposition(i.v,c);
}
v[c].clear();
}
void Init(int N, int A[], int B[], int D[])
{
n = N;
for(i=0;i<=N-2;i++)
{
p = A[i];q = B[i];k = D[i];
p++;q++;
// cout<<p<<" "<<q<<" "<<k<<endl;
v[p].insert({q,k});
v[q].insert({p,k});
}
while((1<<l)<=n)
l++;
for(i=0;i<=n+1;i++)
up[i].resize(l+6);
tout[0] = INT_MAX;
dfs(1,0);
//
centroid_decomposition(1,0);
//cout<<"krai"<<endl;
for(i=1;i<=n;i++)
ans[i] = LLONG_MAX;
}
long long dist(int u,int u2)
{
return raz[u]+raz[u2]-2*raz[lca(u,u2)];
}
void add(int ver)
{
for(j=ver;j!=0;j=par[j])
{
if(lasttime[j]!=cnt)
ans[j] = dist(ver,j),lasttime[j] = cnt;
else ans[j] = min(ans[j],dist(ver,j));
}
}
long long Query(int S, int X[], int T, int Y[])
{
///+1 to all vertices
long long otg = LLONG_MAX;
++cnt;
for(i=0;i<S;i++)
{
add(X[i]+1);
}
for(i=0;i<T;i++)
{
p = Y[i]+1;
for(j=p;j!=0;j=par[j])
if(lasttime[j]==cnt)otg = min(otg,dist(p,j)+ans[j]);
}
return otg;
}