Epidemic control

Luo Valley

In fact, before long I was thinking about the same general understanding

However, due to too konjac

hard to accomplish

 

In January, before about my brush tree dp, and brush to this question

Ah, I get to 0pts good results with dp

 

Anyway, I now understand that

#include<bits/stdc++.h>
#define re return
#define ll long long
#define dec(i,l,r) for(register int i=l;i>=r;--i)
#define inc(i,l,r) for(register int i=l;i<=r;++i) 
using namespace std;
template<typename T>inline void rd(T&x)
{
    char c;bool f=0;
    while((c=getchar())<'0'||c>'9')if(c=='-')f=1;
    x=c^48;
    while((c=getchar())>='0'&&c<='9')x=x*10+(c^48);
    if(f)x=-x;
}

const int maxn=300005;
int cnt,k,n,m,hd[maxn],fa[maxn][21];
int size1,pos[maxn],vis[maxn];

long long dis[maxn][21];

struct node{
    int to,nt,val;
}e[maxn<<1];
inline void add(int x,int y,int z)
{
    e[++k].to=y;e[k].nt=hd[x];hd[x]=k;e[k].val=z;
    e[++k].to=x;e[k].nt=hd[y];hd[y]=k;e[k].val=z;
}


inline void dfs(int x)
{
    for(int i=0;fa[fa[x][i]][i];++i)
    {
        fa[x][i+1]=fa[fa[x][i]][i];
        dis[x][i+1]=dis[x][i]+dis[fa[x][i]][i];
    }
    
    for(int i=hd[x];i;i=e[i].nt)
    {
        int v=e[i].to;
        if(v==fa[x][0])continue;
        fa[v][0]=x;
        dis[v][0]=e[i].val;
        dfs(v);
    }
}

struct lll
{
    int fr,left_dis,id;
    bool operator<(lll c)const
    {
        re left_dis<c.left_dis;
    }
}a[maxn];

int cnta,cntb,need[maxn];
struct lli
{
    int val,id;
    bool operator<(lli c)const
    {
        re val<c.val;
    }
}b[maxn];

inline bool dfs1(int x)
{
    if(vis[x])re 1;
    int siz=0;
    for(int i=hd[x];i;i=e[i].nt)
    {
        int v=e[i].to;
        if(v==fa[x][0])continue;
        siz|=1;
        if(dfs1(v)==0)
        {vis[x]=0;re 0;}
    }
    if(!siz)
        {vis[x]=0;re 0;}
    vis[x]=1;
    re 1;
}

inline bool check(ll x)
{
    cntb=cnta=0;
    inc(i,0,n)vis[i]=0; 
    
    inc(i,1,m)
    {
        int v=pos[i],now=0;
        On Dec (I, 20 is , 0 ) IF (FA [V] [I]> . 1 && DIS [V] [I] + now <= X) {now + = DIS [V] [I]; V = FA [V] [ I];} 
        
        int left = now-DIS-X [V] [ 0 ]; 
        
        IF (FA [V] [ 0 ] == . 1 && left> = 0 )
         // at the boundary point // can return point has been injection or tie 
         // left is a departure from the maximum distance that can be traveled 
            a [++ CNTA] = (LLL) {V, left, CNTA}; 
        
        the else VIS [V] = 1 ; 
    } 
    
    // will not be blocked dot mark 
    for ( int I = HD [ . 1 ]; I; I = E [I] .nt)
    {
         int= V E [I] .to; 
        DFS1 (V); 
    } 
    
    Sort (A + . 1 , A + + CNTA . 1 );
     int Nowa = 0 ; 
    
    
    // find the smallest can not return to the starting node (unblocked) value 
    inc (i , . 1 , CNTA) 
    { 
        IF (VIS [A [I] .fr] && A [I] .left_dis <DIS [A [I] .fr] [! 0 ]) 
        { 
            A [I] .left_dis = - . 1 ; 
            VIS [A [I] .fr] = . 1 ;
             - Nowa; 
        } 
    } 
    
    Sort (A + . 1 , A + + CNTA . 1);
    for(int i=hd[1];i;i=e[i].nt)
    {
        int v=e[i].to;
        if(!vis[v])b[++cntb]=(lli){e[i].val,v};
    }
    sort(b+1,b+cntb+1);
    
    int nowb=1;
    inc(i,nowa+1,cnta)
    {
        if(b[nowb].val<=a[i].left_dis)++nowb;
        if(nowb==cntb+1)re 1;
    }
    
    re 0;
}
int main()
{
freopen("in.txt","r",stdin);
//    freopen("testdata.in","r",stdin);
    int x,y,z;    
    ll l=0,r=0;
    rd(n);
    inc(i,2,n)
    {
        rd(x),rd(y),rd(z);
        add(x,y,z);
        r+=z;
    }
    
    //dfs得到倍增数组 
    for(int i=hd[1];i;i=e[i].nt)
    {
        ++size1;
        int v=e[i].to;
        fa[v][0]=1;dis[v][0]=e[i].val;
        dfs(v);
    }    
    
    rd(m);
    if(m<size1){printf("-1");re 0;}
    
    inc(i,1,m)rd(pos[i]);

    while(l<=r)
    {
        int mid=(l+r)>>1;
        if(check(mid))r=mid-1;
        else l=mid+1;
    }
    
    printf("%lld",l);
    re 0;
} 

 

Guess you like

Origin www.cnblogs.com/lsyyy/p/11529933.html