标签:tps 不能 P20 etc 怎样 freopen pen ace lld
注意数组范围等细节处理。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const ll N=5e5+100;
ll n,m,tot,a[N],rd[N],v[N],ver[N<<1],Next[N<<1],lin[N],edge[N],f[N][35];ll g[N][35];
ll used[N],top1,top2;
ll zx[N];ll rx[N];
bool flag;
struct node{
ll rest;ll id;
}c[N],d[N];
ll read(){
char ch=getchar();ll num=0,f=1;
while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch)){num=(num<<1)+(num<<3)+(ch^48);ch=getchar();}
return num*f;
}
void add(ll x,ll y,ll z){ver[++tot]=y;Next[tot]=lin[x];lin[x]=tot;edge[tot]=z;rd[y]++;}
bool cmp(node x,node y){return x.rest>y.rest;}
void dfs(ll x,ll fa,ll id){
f[x][0]=fa;g[x][0]=edge[id];
for(ll i=1;i<=20;++i) f[x][i]=f[f[x][i-1]][i-1],g[x][i]=(ll)(g[x][i-1]+g[f[x][i-1]][i-1]);
for(ll i=lin[x];i;i=Next[i]){
ll y=ver[i];
if(y==fa) continue;
dfs(y,x,i);
}
}
void Dfs(ll x,ll fa,ll now){
if(v[x]) {now=1;return;}
if(now==0&&rd[x]==1){ flag=0;return ;}
for(ll i=lin[x];i;i=Next[i]){
ll y=ver[i];
if(y==fa) continue;
Dfs(y,x,now);
}
}
bool check(ll mid){
memset(v,0,sizeof(v));
memset(rx,0,sizeof(rx));
memset(zx,0,sizeof(zx));
memset(used,0,sizeof(used));
top1=0,top2=0;
for(ll i=1;i<=m;++i){
ll x=a[i],num=0;
for(ll j=20;j>=0;--j)//3.上提军队
if(f[x][j]>1&&num+g[x][j]<=mid)
num+=g[x][j],x=f[x][j];
if(f[x][0]==1&&num+g[x][0]<=mid){//4.处理剩余路程
c[++top1].rest=mid-num-g[x][0],c[top1].id=i;
if(!zx[x]||c[top1].rest<rx[x])
rx[x]=c[top1].rest,zx[x]=i;
}
else v[x]=1;
}
for(ll i=lin[1];i;i=Next[i]){
ll y=ver[i];
flag=1;Dfs(y,1,0);
if(!flag) d[++top2].rest=edge[i],d[top2].id=y;
}
sort(c+1,c+top1+1,cmp);
sort(d+1,d+top2+1,cmp);
ll now=1;used[0]=1;
for(ll i=1;i<=top2;++i){
if(!used[zx[d[i].id]]&&zx[d[i].id]){used[zx[d[i].id]]=1;continue;}
while(now<=top1&&(used[c[now].id]||c[now].rest<d[i].rest))++now;
if(now>top1)return 0;used[c[now].id]=1;
}
return 1;
}
int main(){
//freopen("1.in","r",stdin);
n=read();//memset(g,0x3f,sizeof(g));
for(ll i=1;i<n;++i){
ll x=read(),y=read(),z=read();
add(x,y,z);add(y,x,z);
}
m=read();
for(ll i=1;i<=m;++i) a[i]=read();
dfs(1,0,0);
ll l=0,r=1e15;
while(l+1<r){
ll mid=l+r>>1;
if(check(mid)) r=mid;
else l=mid;
}
if(check(l)) printf("%lld\n",l);
else printf("%lld\n",r);
return 0;
}
标签:tps 不能 P20 etc 怎样 freopen pen ace lld
原文地址:https://www.cnblogs.com/kgxw0430/p/10593502.html