bzoj 2599 [IOI2011]Race 未调完_点分治

Code:

// luogu-judger-enable-o2
// luogu-judger-enable-o2
#include <bits/stdc++.h>
#define setIO(s) freopen(s".in","r",stdin) 
#define maxn 1000000
#define inf 0x7f7f7f
using namespace std;  
int hd[maxn],to[maxn],nex[maxn],val[maxn],f[maxn],vis[maxn],siz[maxn],dep[maxn],ans,cur=0; 
int cnt,n,k,root,sn,d[2]; 
void addedge(int u,int v,int c)
{
    nex[++cnt] = hd[u],hd[u] = cnt,to[cnt] = v,val[cnt] = c; 
}
struct Point{
    int dis,tot; 
    Point(int dis = 0,int tot = 0):dis(dis),tot(tot){} 
    bool operator<(Point b)const{
        return b.dis != dis ? b.dis>dis : b.tot > tot;  
    }
}point[2][maxn];
void getdis(int u,int fa,int tot)
{
    point[cur][++d[cur]]=Point(dep[u],tot); 
    for(int i = hd[u]; i ; i = nex[i])
    {
        if(vis[to[i]] || to[i] == fa) continue;  
        dep[to[i]] = dep[u] + val[i],getdis(to[i],u,tot + 1); 
    }     
}
void GetRoot(int u,int ff)
{
    siz[u] = 1,f[u] = 0;       
    for(int i = hd[u]; i ; i = nex[i])
    {
        if(vis[to[i]] || to[i] == ff) continue;    
        GetRoot(to[i],u); 
        siz[u] += siz[to[i]];  
        f[u] = max(f[u], siz[to[i]]); 
    }
    f[u] = max(f[u], sn - siz[u]); 
    if(f[u] < f[root]) root = u; 
} 
void DFS(int u)
{
    vis[u] = 1, dep[u] = 0, cur = 0, d[cur] = 0,d[cur^1] = 1,point[cur^1][1] = Point(0,0);  
    for(int i = hd[u]; i ; i = nex[i])
    {
        if(vis[to[i]]) continue;  
        dep[to[i]] = val[i]; 
        d[cur] = 0; 
        root = 0,sn = siz[to[i]],GetRoot(to[i],u), DFS(root);   
        getdis(to[i],0,1);      
        sort(point[cur]+1,point[cur]+1+d[cur]); 
        int m = 1;   
        for(int j = 2;j <= d[cur]; ++j) if(point[cur][j].dis!=point[cur][j-1].dis) point[cur][++m]=point[cur][j];       
        d[cur] = m;     
        int p1 = 1,p2 = d[cur^1];                
        while(p1 <= d[cur] && p2 >=1)
        {         
            if(point[cur][p1].dis + point[cur^1][p2].dis == k) ans = min(ans,point[cur][p1].tot + point[cur^1][p2].tot), ++p1,--p2; 
            if(point[cur][p1].dis + point[cur^1][p2].dis < k) ++p1; 
            if(point[cur][p1].dis + point[cur^1][p2].dis > k) --p2; 
        }
        for(int j = 1;j <= d[cur]; ++j) point[cur^1][++d[cur^1]] = point[cur][j]; 
        sort(point[cur^1]+1,point[cur^1]+1+d[cur^1]);    
        m = 1;    
        for(int j=2;j<=d[cur^1];++j) if(point[cur^1][j].dis!=point[cur^1][j-1].dis)point[cur^1][++m]=point[cur^1][j];       
        d[cur^1]=m, d[cur]=0;               
    }
} 
int main()
{
    setIO("input"); 
    scanf("%d%d",&n,&k);
    for(int i = 1,a,b,c;i < n; ++i) scanf("%d%d%d",&a,&b,&c),addedge(a+1,b+1,c),addedge(b+1,a+1,c); 
    ans = inf, vis[0] = 1,f[0] = inf,sn = n,root = 0, GetRoot(1,0),DFS(root); 
    printf("%d\n",ans==inf?-1:ans);  
    return 0; 
}

  

猜你喜欢

转载自www.cnblogs.com/guangheli/p/10939790.html