P1084 [NOIP2012 提高组] 疫情控制
一棵树 n 个节点 初始m个军队驻扎在若干个点,问最短什么时候 所有从rt==1 到 叶节点 的路全部封死
》因为是树-> 贪心->越上面越好
》答案具有单调性 越大越好-> 二分(准确即可)
》》pre_bfs ->fa[][],dis[][] // shangyi 1.一定到不了直接标记 2.超过的限制待定 存储// dfs->有多少没有被占领的dep==2的子节点 标记//
#include<cstdio> #include<iostream> #include<algorithm> #include<queue> #include<vector> #include<bits/stdc++.h> #define ll long long #define ddd printf("-----------------------\n"); using namespace std; const int maxn=5e4+10 ; pair<ll,int> h[maxn]; ll dis[maxn<<1][30],l,r=1,ans; int fa[maxn][30],dep[maxn],query[maxn],sta[maxn],need[maxn],htot,tim[maxn],ttot,ned[maxn],ntot; int head[maxn],to[maxn<<1],nxt[maxn<<1],w[maxn<<1],tot; int n,m,ok; void add(int u,int v,int val){ to[++tot]=v,nxt[tot]=head[u],head[u]=tot,w[tot]=val; } void bfs() { queue<int> q; q.push(1),dep[1]=1; while(!q.empty()) { int u=q.front(); q.pop(); for(int i=head[u];i;i=nxt[i]) { int v=to[i]; if(dep[v]) continue; dep[v]=dep[u]+1; fa[v][0]=u, dis[v][0]=w[i]; for(int j=1;j<=21;j++) fa[v][j]=fa[fa[v][j-1]][j-1],dis[v][j]=dis[v][j-1]+dis[fa[v][j-1]][j-1]; q.push(v);// } } } int dfs(int u) { int leaf=1; if(sta[u]==1) return 1; for(int i=head[u];i;i=nxt[i]) { int v=to[i]; if(dep[v]<dep[u]) continue; leaf=0; if(dfs(v)==0) return 0; } if(leaf==1) return 0; return 1; } int check(ll lim) { memset(ned,0,sizeof(ned)); memset(tim,0,sizeof(tim)); memset(sta,0,sizeof(sta)); memset(need,0,sizeof(need)); memset(h,0,sizeof(h)); ntot=ttot=htot=0; for(int i=1;i<=m;i++) { ll tmp=0;int x=query[i]; for(int j=21;j>=0;j--)// { if(fa[x][j]>1&&tmp+dis[x][j]<=lim) tmp+=dis[x][j],x=fa[x][j]; } if(fa[x][0]==1&&tmp+dis[x][0]<=lim) h[++htot]=make_pair(lim-tmp-dis[x][0],x);// else sta[x]=1; } for(int i=head[1];i;i=nxt[i]){ int v=to[i]; if(dfs(v)==0) need[v]=1;// } for(int i=1;i<=htot;i++){ if(need[h[i].second]==1&&h[i].first<=dis[h[i].second][0]) need[h[i].second]=0,sta[h[i].second]=1; else tim[++ttot]=h[i].first; } for(int i=head[1];i;i=nxt[i]){ int v=to[i]; if(need[v]==1) ned[++ntot]=dis[v][0]; } if(ntot>ttot) return 0; sort(tim+1,tim+1+ttot),sort(ned+1,ned+1+ntot); int i=1,j=1; while(i<=ttot&&j<=ntot){ if(tim[i]>=ned[j]){ i++,j++;} else i++; } if(j<=ntot) return 0; else return 1; } int main() { ios::sync_with_stdio(false); cin>>n; for(int i=1;i<=n-1;i++){ int u,v,val;cin>>u>>v>>val; add(u,v,val),add(v,u,val); r+=val; } bfs(); cin>>m; for(int i=1;i<=m;i++) cin>>query[i]; while(l<=r) { ll mid=l+r>>1; if(check(mid)){ r=mid-1; ans=mid; ok=1; } else l=mid+1; } if(ok==0){ cout<<"-1\n"; return 0; } cout<<ans<<'\n'; return 0; }

浙公网安备 33010602011771号