记录编号 274990 评测结果 AAAAAAAAAAAAAAAAAAAAT
题目名称 [SPOJ 1825] 免费旅行II 最终得分 95
用户昵称 GravatarTenderRun 是否通过 未通过
代码语言 C++ 运行时间 15.922 s
提交时间 2016-06-30 19:27:10 内存使用 26.64 MiB
显示代码纯文本
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int maxn=400010;
const int INF=2147483647;
int n,m,k,c[maxn];
int cnt,fir[maxn],nxt[maxn*2],to[maxn*2],val[maxn*2];
void addedge(int a,int b,int v){
	nxt[++cnt]=fir[a];
	fir[a]=cnt;
	val[cnt]=v;
	to[cnt]=b;
}

bool vis[maxn];
int N,rt,sz[maxn],son[maxn];
void Get_RT(int x,int fa){
	sz[x]=1;son[x]=0;
	for(int i=fir[x];i;i=nxt[i])
		if(to[i]!=fa&&!vis[to[i]]){
			Get_RT(to[i],x);
			sz[x]+=sz[to[i]];
			son[x]=max(son[x],sz[to[i]]);
		}
	son[x]=max(son[x],N-sz[x]);
	if(!rt||son[x]<son[rt])rt=x;	
}

int st[maxn],stot;
int pt[maxn],ptot;
int tmp[maxn];

int dis[maxn],sum[maxn];

void DFS(int x,int fa){
	pt[++ptot]=x;
	for(int i=fir[x];i;i=nxt[i])
		if(!vis[to[i]]&&to[i]!=fa){
			dis[to[i]]=dis[x]+val[i];
			sum[to[i]]=sum[x]+c[to[i]];
			DFS(to[i],x);
		}
}

bool cmp(int x,int y){
	if(sum[x]!=sum[y])
	return sum[x]<sum[y];
	return dis[x]>dis[y];
}

void Get(int *q,int &tot){
	int p=0;
	sort(q+1,q+tot+1,cmp);
	for(int i=1;i<=tot;i++){
		if(p&&dis[q[i]]<=dis[tmp[p]])continue;
		tmp[++p]=q[i];
	}
	for(int i=1;i<=p;i++)q[i]=tmp[i];
	tot=p;
}

int Get_Max(int x,int d,int v){
	ptot=0;
	dis[x]=d;
	sum[x]=c[x];
	
	DFS(x,0);
	Get(pt,ptot);
	
	int l=1,r=ptot,ret=-INF;
	while(l<=stot&&r>=1){
		if(sum[st[l]]+sum[pt[r]]>k)r--;
		else ret=max(ret,dis[st[l]]+dis[pt[r]]),l+=1;
	}
	
	for(int i=1;i<=ptot;i++)
		st[stot+i]=pt[i],sum[pt[i]]+=v;
	stot+=ptot;	
	Get(st,stot);	
	return ret;
}

struct Node{
	int x,val;	
	Node(int x_=0,int val_=0){
		x=x_;val=val_;
	}
};

bool cmpx(Node x,Node y){
	return sz[x.x]<sz[y.x];
}


Node stack[maxn];
int top;
int Solve(int x){
	int ret=-INF;dis[x]=0;
	int l=top+1,r;
	vis[x]=true;st[stot=1]=x;sum[x]=c[x];
	for(int i=fir[x];i;i=nxt[i])
		if(!vis[to[i]])stack[++top]=Node(to[i],val[i]);
	r=top;
	sort(st+l,st+r+1,cmpx);	
	for(int i=l;i<=r;i++)ret=max(ret,Get_Max(stack[i].x,stack[i].val,c[x]));
	
	for(int i=l;i<=r;i++){
		N=sz[stack[i].x];rt=0;
		Get_RT(stack[i].x,0);
		ret=max(ret,Solve(rt));
	}
	return ret;	
}

int main(){
	freopen("freetourII.in","r",stdin);
	freopen("freetourII.out","w",stdout);
	scanf("%d%d%d",&n,&k,&m);
	while(m--){
		int x;
		scanf("%d",&x);
		c[x]=1;
	}
	for(int i=1,a,b,v;i<n;i++){
		scanf("%d%d%d",&a,&b,&v);
		addedge(a,b,v);
		addedge(b,a,v);
	}
	N=n;rt=0;Get_RT(1,0);
	int ans=Solve(rt);
	printf("%d\n",ans==-INF?0:ans);
	return 0;
}