专栏文章

题解:AT_abc401_f [ABC401F] Add One Edge 3

AT_abc401_f题解参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@mioc8nsi
此快照首次捕获于
2025/12/02 16:50
3 个月前
此快照最后确认于
2025/12/02 16:50
3 个月前
查看原文
模拟赛题。
连接 (i,j)(i,j) 两点后,新直径只可能为 d1,d2,disi+disj+1d_1,d_2,dis_i+dis_j+1,其中 disidis_iiiT1T_1 中最远的点的距离,disjdis_jjjT2T_2 中最远的点的距离。
d1,d2d_1,d_2 两次 BFS 求出,关键在于 disi,disjdis_i,dis_j 怎么求。
直径有一条性质:从 ii 出发到达的最远点必定是直径的端点。那么从直径的两端出发 BFS 即可求得 disdis
最后固定 ii,二分一下 disi+disj+1dis_i+dis_j+1 从什么位置开始贡献到答案,前缀和搞一搞就做完了。
CPP
#include <bits/stdc++.h>
#define int long long
#define umap unordered_map
#define vint vector<int>
#define ll long long
#define pii pair<int,int>
#define all(x) x.begin(),x.end()
#define ull unsigned long long
#define uint unsigned int
#define rg register
#define il inline
#define rep(i,a,b) for(int i=(a);i<=(b);++i)
#define per(i,a,b) for(int i=(a);i>=(b);--i)
#define sqr(x) ((x)*(x))
using namespace std;
const int INF=0x3f3f3f3f;
inline int read(){
    int w=0,f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9'){
        if(ch=='-') f=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9'){
        w=(w<<1)+(w<<3)+(ch^48);
        ch=getchar();
    }
    return w*f;
}
inline void write(int x){
    if(x<0){
        putchar('-');
        x=-x;
    }
    if(x>9) write(x/10);
    putchar(x%10+'0');
}

const int N=2e5+10;
struct graph{
    int n,d,s,t,a[N];
    vint G[N];
    void add(int u,int v){
        G[u].push_back(v);
        G[v].push_back(u);
    }
    int dis[N],vis[N];
    void bfs(int s){
        memset(dis,0,sizeof dis),memset(vis,0,sizeof vis);
        queue<int> Q;
        Q.push(s);
        while(!Q.empty()){
            int u=Q.front();Q.pop();
            vis[u]=1;
            for(int v:G[u]){
                if(vis[v]) continue;
                dis[v]=dis[u]+1;Q.push(v);
            }
        }
    }
    int get_d(){
        bfs(1);
        s=max_element(dis+1,dis+n+1)-dis;
        bfs(s);
        t=max_element(dis+1,dis+n+1)-dis;
        return d=dis[t];
    }
    void get_a(){
        bfs(s);
        memcpy(a,dis,sizeof a);
        bfs(t);
        rep(i,1,n) a[i]=max(a[i],dis[i]);
    }
}G1,G2;
int d1,d2,d,pre[N];
signed main(){
    #ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
    #endif
    G1.n=read();
    for(int i=1,u,v;i<G1.n;++i){
        u=read(),v=read();
        G1.add(u,v);
    }
    G2.n=read();
    for(int i=1,u,v;i<G2.n;++i){
        u=read(),v=read();
        G2.add(u,v);
    }
    d1=G1.get_d(),d2=G2.get_d();
    d=max(d1,d2);
    G1.get_a(),G2.get_a();
    int ans=0;
    sort(G2.a+1,G2.a+G2.n+1);
    rep(i,1,G2.n) pre[i]=pre[i-1]+G2.a[i];
    for(int i=1;i<=G1.n;++i){
        int k=G1.a[i]+1;
        int pos=lower_bound(G2.a+1,G2.a+G2.n+1,d-k)-G2.a;
        if(pos==G2.n+1) ans+=d*G2.n;
        else{
            ans+=(pos-1)*d;
            ans+=pre[G2.n]-pre[pos-1]+(G2.n-pos+1)*(1+G1.a[i]);
        }
    }
    cout<<ans<<endl;
    #ifndef ONLINE_JUDGE
    fprintf(stderr,"%f\n",1.0*clock()/CLOCKS_PER_SEC);
    #endif
    return 0;
}

评论

0 条评论,欢迎与作者交流。

正在加载评论...