【刷题】【lca】运输计划

完完整整自己做出来啦,1A,可高兴了

就是花了一个半小时,

#include<cstdio>
#include<cstdlib>
#include<algorithm>
using namespace std;
inline int read()
{
    int x=0;char c=getchar();
    while(c<'0' || c>'9' ) c=getchar();
    while(c>='0'&&c<='9' ) x=(x<<3)+(x<<1)+c-'0',c=getchar();
    return x;
}
int n,m;
const int N=3e5+3,M=3e5+3;

int tot,head[N];
int ev[M<<1],enx[M<<1];
long long ew[M<<1];
void add(int u,int v,long long w)
{
    ev[++tot]=v,ew[tot]=w,enx[tot]=head[u],head[u]=tot;
    ev[++tot]=u,ew[tot]=w,enx[tot]=head[v],head[v]=tot;
}

int fa[N][20],dep[N]; long long dis[N][20];
int lca;long long length;
void dfs(int rt,int f)
{
    for(int i=1;i<20 && fa[rt][i-1] ;i++ )
        dis[rt][i]=dis[fa[rt][i-1] ][i-1] +dis[rt][i-1],
        fa[rt][i]=fa[fa[rt][i-1] ][i-1];
    
    for(int i=head[rt];i;i=enx[i])
        if(ev[i]!=f ) 
        {
            fa[ev[i]][0]=rt,dep[ev[i]]=dep[rt]+1,dis[ev[i]][0]=ew[i];
            dfs(ev[i],rt);
        }
}
void LCA(int u,int v)
{
    length=0;
    if(dep[u]<dep[v] ) swap(u,v);
    
    int dist=dep[u]-dep[v];
    for(int i=1,j=0;i<=dist;i<<=1,j++)
        if(dist&i ) length+=dis[u][j],u=fa[u][j];
    if(u==v )
    {
        lca=u;
        return ;
    }
    
    for(int i=19;i>=0;i--)
        if(fa[u][i]!=fa[v][i] )
            length+=dis[u][i]+dis[v][i],
            u=fa[u][i],v=fa[v][i];
    length+=dis[u][0]+dis[v][0],lca=fa[u][0];
}

struct node
{
    int fr,ed,lca; long long dis;
    bool operator < (const node & o ) const
    { return dis>o.dis; }
}ask[M];

long long ans,main_ans;
bool check(int u,int v,long long dd)
{
    LCA(u,v);
    int t=lca;
    if(t!=v ) return false;
    ans=max(ans,dd);
    return true;
}
int main()
{
    n=read(),m=read();
    for(int i=1;i<n;i++)
    {
        int u=read(),v=read(); long long w;
        scanf("%lld",&w);
        add(u,v,w);
    }
    dfs(1,0);
    for(int i=1;i<=m;i++)
    {
        ask[i].fr =read(),ask[i].ed =read();
        if(dep[ask[i].fr ] < dep[ask[i].ed ] ) swap(ask[i].fr ,ask[i].ed );
        LCA(ask[i].fr ,ask[i].ed );
        ask[i].dis =length,ask[i].lca =lca;
    }
    sort(ask+1,ask+m+1);
    
    int pt=ask[1].lca ,mark=0;
    main_ans=ask[1].dis ;
    for(int x=ask[1].fr ;x!=pt; )
    {
        ans=ask[1].dis -dis[x][0];
        int i;long long sub=dis[x][0];
        for(i=2;i<=m && ans<ask[i].dis ;i++)
        {    
            if(dep[ask[i].lca ] >= dep[x] || (dep[ask[i].fr ] < dep[x] && dep[ask[i].ed ] < dep[x] ) ) 
            {
                ans=max(ans,ask[i].dis );
                break;
            }
            
            if(dep[ask[i].fr ] >= dep[x] && check(ask[i].fr ,x,ask[i].dis -sub) ) continue; //能选,就在函数中更新,然后continue 
            else if (dep[ask[i].ed ] >= dep[x] && check(ask[i].ed ,x,ask[i].dis -sub) ) continue;
            else //如果不能选,还是退出吧 
            {
                ans=ask[i].dis ;
                break;
            }
        }
        main_ans=min(ans,main_ans);        
        
        x=fa[x][0] ;
        if(x==pt && !mark ) x=ask[1].ed ,mark=1;
    }
    printf("%lld\n",main_ans);
    return 0;
}
View Code

猜你喜欢

转载自www.cnblogs.com/xwww666666/p/11822765.html