P1084 疫情控制

#include<bits/stdc++.h>
using namespace std;
struct node{
    int nxt,dis,to;
}eg[51000*2];
#define ll long long
void adde(int from,int to,int dis)
{
    eg[++ne].to=to;
    eg[ne].dis=dis;
    eg[ne].nxt=head[from];
    head[from]=ne;
}
struct nd{int it,re;}num[51000];
int cmp(nd x,nd y){return x.re<y.re;}
int cmp2(int a,int b){return d[a][0]<d[b][0];}
int n,head[51000],m,ne,fa[51000][22],d[51000][22]a,b,c,id[51000],q[51000];
int se[51000];
int dfs(int u,int f){
    for(int i=head[u];i;i=eg[i].nxt)
    {
        int v=eg[i].to;
        if(v==fa)continue;
        fa[v][0]=u;
        d[v][0]=eg[i].dis;
        dfs(v,u);
    }
}
int dfs2(int u,int f){
    int t=0
    for(int i=head[u];i;i=eg[i].nxt)
    {
        int v=eg[i].to;
        if(v==fa)continue;
        t++;
        dfs(v,u);
    }
    if(!cnt)se[u]=1;
}
int dfs3(int u,int f){
    if(!bol)
    {
    int t=0
    for(int i=head[u];i;i=eg[i].nxt)
    {
        int v=eg[i].to;
        if(v==fa)continue;
        t++;
        dfs(v,u);
    }
    if(!cnt)if(!se[u])bol=1;    
    }
}
int check(int w)
{
    int cnt=0;
    for(int i=1;i<=m;i++)
    {
        ll rest=w;
        int di=id[i],flg=0;
        for(int j=22;j>=0;j--)
        {
            if(rest-d[di][j]>=0)
            {
                if(fa[di][j]==1)flg=1,break;
                else rest-=d[di][j];
            }
         } 
        if(!flg)
        dfs2(di,fa[di][0]);
        else {
            if(rest<2*d[di][0])
            dfs2(di,fa[di][0]);
            else {
            num[++cnt].it=di;
            num[cnt].re=rest-d[di][0];
            }    
        }
    }
    int sum=0;
    for(int i=head[1];i;i=eg[i].nxt)
    {
        bol=0;
        dfs3(eg[i].to,1);
        if(bol)q[++sum]=eg[i].to;
    }
    sort(num+1,num+1+cnt,cmp);
    sort(q+1,q+1+sum,cmp2);
    
}
int main()
{
    long long r=0;
    cin>>n;
    for(int i=1;i<n;i++)
    {
        cin>>a>>b>>c;
        adde(a,b,c);
        adde(b,a,c);
        ans+=c;
    }
    cin>>m;
    for(int i=1;i<=m;i++)cin>>id[i];
    fa[1][0]=1;
    dfs(1,1);
    for(int i=1;i<=22;i++)
    for(int j=1;j<=n;j++)
    d[j][i]=d[j][i-1]+d[fa[j][i-1]][i-1];
    long long l=0,mid;
    while(l<=r)
    {mid=(l+r)>>1;
        if(check(mid))r=mid;
        else l=mid+1;
    }
    cout<<r;
    
}

 

上一篇:[c++指针教程]用简单链表练习指针


下一篇:51Nod1227 平均最小公倍数