记录编号 193837 评测结果 AAAAAAAAAA
题目名称 [NOIP 2012]疫情控制 最终得分 100
用户昵称 Gravatarmikumikumi 是否通过 通过
代码语言 C++ 运行时间 1.751 s
提交时间 2015-10-15 16:46:32 内存使用 20.64 MiB
显示代码纯文本
#include<cstdio>
#include<deque>
#include<set>
#include<iostream>
#include<cstring>
using namespace std;
const int SIZEN=50010,maxn=0x7fffffff/2;
typedef long long LL;
//二分时间,处理出军队到各点的时间
int n,m;
class miku
{
public:
	int to,lo;
	miku(){}
	miku(int b,int c)
	{
		to=b,lo=c;
	}
};
deque<miku> s[50010];
multiset<LL> c[SIZEN];
multiset<LL> G;
int f[50010]={0};
int w[50010]={0};
int se[50010]={0},cut[SIZEN];//驻军地点
bool arr[50010];
bool P[SIZEN];
LL ma;
void add(int fr,int to,int lo)
{
	s[fr].push_back(miku(to,lo));
	s[to].push_back(miku(fr,lo));
}
void dfs(int x,int fa)
{
	for(int i=0;i<s[x].size();i++)
	{
		if(s[x][i].to==fa) continue;
		f[s[x][i].to]=x;w[s[x][i].to]=s[x][i].lo;
		dfs(s[x][i].to,x);
	}
}
void climb(int x,int t)
{
	int tem=se[x];
	while(tem!=1&&t>=w[tem])
	{
		if(f[tem]==1) c[tem].insert(t-w[tem]);
		t-=w[tem];
		tem=f[tem];
	}
	if(tem!=1) arr[tem]=1;
	else G.insert(t);
}
bool check_con(int x)
{
	if(arr[x]==1) return 1;
	if(s[x].size()==1) return 0;
	for(int i=0;i<s[x].size();i++)
	{
		int v=s[x][i].to;
		if(v==f[x]) continue;
		if(!check_con(v)) return 0;
	}
	arr[x]=1;return 1;
}
bool check(int t)
{
	G.clear();
	for(int i=0;i<s[1].size();i++) c[s[1][i].to].clear();
	memset(arr,0,sizeof(arr));
	for(int i=1;i<=m;i++) climb(i,t);
	multiset<LL>::iterator key,it;
	//cout<<"G:";for(key=G.begin();key!=G.end();key++) cout<<*key<<" ";
	//cout<<endl;
	for(int i=0;i<s[1].size();i++)
	{
		int v=s[1][i].to;
		if(c[v].size()>0)
		{
			if(check_con(v)) continue;
			arr[v]=1;
			key=c[v].begin();
			it=G.lower_bound(w[v]);
			//cout<<*it<<" "<<*key<<" "<<v<<" "<<w[v]<<endl;
			//cout<<"G:";for(key=G.begin();key!=G.end();key++) cout<<*key<<" ";
			//cout<<endl;
			if(G.find(*key)!=G.end()&&(it==G.end()||*key<*it)) G.erase(G.find(*key));
			else G.erase(it);
		}
	}
	for(int i=0;i<s[1].size();i++)
	{
		int v=s[1][i].to;
		if(check_con(v)) continue;
		//cout<<v<<" "<<w[v]<<endl;
		//cout<<"G:";for(key=G.begin();key!=G.end();key++) cout<<*key<<" ";
		//cout<<endl;
		key=G.lower_bound(w[v]);
		if(key==G.end()) return 0;
		G.erase(key);
	}
	return 1;
}
void work()
{
	LL l=0,r=ma;
	scanf("%d",&m);
	for(int i=1;i<=m;i++) {scanf("%d",&se[i]);P[se[i]]=1;}
	//cout<<P[1]<<endl;
	if(m<s[1].size()) {printf("-1");return;}
	while(l<r)
	{
		int mid=(l+r)/2;
		if(check(mid)) r=mid;
		else l=mid+1;
		//cout<<mid<<endl;
	}
	printf("%d",r);
}
int main()
{
	freopen("blockade.in","r",stdin);
	freopen("blockade.out","w",stdout);
	scanf("%d",&n);
	int fr,to,lo;
	for(int i=1;i<n;i++)
	{
		scanf("%d%d%d",&fr,&to,&lo);
		add(fr,to,lo);ma+=lo;
	}
	dfs(1,0);
	//cout<<ma<<endl;
	//for(int i=0;i<s[1].size();i++) cout<<s[1][i].to<<" "<<w[s[1][i].to]<<endl;
	//cout<<w[1752]<<endl;
	work();
	return 0;
}