题解:P11241 「KTSC 2024 R2」病毒
考虑一个建图方式:建立
考虑优化“
这样,点分治过程中每个连通块的点、边数为
还有一些优化。对于每个中转点,我们再拆成入点和出点,这样只有
#include<bits/stdc++.h>
#define rep(i,j,k) for(int i=j;i<=k;i++)
#define repp(i,j,k) for(int i=j;i>=k;i--)
#define pii pair<int,int>
#define mp make_pair
#define fir first
#define sec second
#define ls(x) (x<<1)
#define rs(x) ((x<<1)|1)
#define lowbit(i) (i&-i)
#define qingbai qwq
using namespace std;
typedef long long ll;
const int N=1e5+5,M=2e6+5,mo=1e9+7;
const ll inf=(ll)1e18+7;
void read(int &a){
int x=0,w=1;
char ch=getchar();
while(!isdigit(ch)){
if(ch=='-')w=-1;
ch=getchar();
}
while(isdigit(ch)){
x=(x<<3)+(x<<1)+ch-'0';
ch=getchar();
}
a=x*w;
}
int n,m,p[N],d[N],c[N];
vector<int>et[N];
int cntp,id[N];
vector<int>perc[N];
int maxs[N],sz[N],rt,tot;
bool vis[N];
void dfs1(int x,int f){
maxs[x]=0,sz[x]=1;
for(auto j:et[x]){
if(vis[j]||j==f)continue;
dfs1(j,x),sz[x]+=sz[j],maxs[x]=max(maxs[x],sz[j]);
}
maxs[x]=max(maxs[x],tot-sz[x]);
if(maxs[x]<maxs[rt])rt=x;
}
vector<pii>e[N*45];
int dep[N],idd[N],maxd=0;
void dfs2(int x,int f){
dep[x]=dep[f]+1,maxd=max(maxd,dep[x]);
for(auto j:et[x]){
if(j==f||vis[j])continue;
dfs2(j,x);
}
}
void dfs3(int x,int f){
for(auto j:et[x])
if(j!=f&&!vis[j])dfs3(j,x);
for(auto j:perc[x]){
int topos=min(maxd,d[j]-dep[x]);
if(topos<0)continue;
e[id[j]].push_back(mp(idd[topos],0));
e[idd[topos]+1].push_back(mp(id[j],0));
}
e[idd[dep[x]]].push_back(mp(x,0));
e[x+n].push_back(mp(idd[dep[x]]+1,0));
}
void dfz(int x){
maxd=0,dep[0]=-1,dfs2(x,0);
rep(i,0,maxd)
idd[i]=++cntp,cntp++;
rep(i,1,maxd){
e[idd[i]].push_back(mp(idd[i-1],0));
e[idd[i-1]+1].push_back(mp(idd[i]+1,0));
}
dfs3(x,0);
vis[x]=1;
for(auto j:et[x]){
if(vis[j])continue;
rt=0,tot=sz[j],dfs1(j,x),dfz(rt);
}
}
ll dis[N*45];
bool visd[N*45];
void dij(){
queue<pair<ll,int>>q;
priority_queue<pair<ll,int>,vector<pair<ll,int>>,greater<pair<ll,int>>>pq;
rep(i,1,cntp)
dis[i]=inf,visd[i]=0;
dis[id[1]]=0,pq.push(mp(0ll,id[1]));
while(!q.empty()||!pq.empty()){
int x;ll v;
if(!q.empty())tie(v,x)=q.front(),q.pop();
else tie(v,x)=pq.top(),pq.pop();
if(visd[x])continue;
visd[x]=1;
for(auto j:e[x]){
if(visd[j.fir]||dis[j.fir]<=dis[x]+j.sec)continue;
dis[j.fir]=dis[x]+j.sec;
if(!j.sec)q.push(mp(dis[j.fir],j.fir));
else pq.push(mp(dis[j.fir],j.fir));
}
}
}
vector<ll>ans;
vector<long long> find_spread(int N, int M, vector<int> A, vector<int> B, vector<int> P, vector<int> D, vector<int> C){
n=N,m=M,cntp=2*n;
rep(i,0,n-2)
et[A[i]+1].push_back(B[i]+1),et[B[i]+1].push_back(A[i]+1);
rep(i,1,m)
p[i]=P[i-1]+1,d[i]=D[i-1],perc[p[i]].push_back(i);
rep(i,1,n)
c[i]=C[i-1];
rep(i,1,m)
id[i]=++cntp;
tot=n,rt=0,maxs[0]=n+2,dfs1(1,0),dfz(rt);
rep(i,1,n)
e[i].push_back(mp(i+n,c[i]));
dij();
rep(i,1,m){
if(dis[id[i]]==inf)ans.push_back(-1);
else ans.push_back(dis[id[i]]);
}
return ans;
}