Intrepid climber |
Time Limit: 2000ms, Special Time Limit:5000ms, Memory Limit:65536KB |
Total submit users: 16, Accepted users: 15 |
Problem 13309 : No special judgement |
Problem description |
Who would guess? You climbed the highest mountain of your city. You are so excited about it that you need to tell it to all your friends, and you decided to start with those that are trying to be exactly where you are at this precise moment. |
Input |
|
Output |
The first line contains two integers N and F (1 ≤ F < N ≤ 10^5), representing respectively the number of landmarks and the number of your friends that are climbing the mountain. Landmarks are identified with distinct integers from 1 to N, being 1 the top of the mountain, where you initially are. Each of the next N − 1 lines describes a different track with three integers A, B and C, indicating that there is a track from A to B that goes down and requires an amount C of energy to be climbed (1 ≤ A ≤ N, 2 ≤ B ≤ N, A 6= B and 1 ≤ C ≤ 100). The next line contains F different integers L1,L2,...,LF (2 ≤ Li≤ N for i = 1,2,...,F) representing the landmarks where your friends are. You may assume that the tracks between landmarks are such that there exists exactly one route that goes down from the top of the mountain to each other landmark. |
Sample Input |
Sample input 1 6 2 1 2 2 2 4 2 1 3 3 3 6 3 3 5 1 5 2 Sample input 2 4 2 1 2 2 1 3 1 3 4 2 2 4 Sample input 3 4 2 1 4 1 1 3 1 4 2 2 2 4 |
Sample Output |
Sample output 1 2 Sample output 2 2 Sample output 3 0 |
Problem Source |
ICPC Latin American Regional ? 2014 |
从1节点开始 要走到f个节点 向下走不要消耗能量 向上走需要消耗能量 能量值为边的权值
两次dfs 第一次搜索有哪些点是必须要走到的 第二次记录从1节点到各节点的权值和
用总的权值和减去需要消耗能量最大的那个节点 即最后走到这个点就不需要再走了
#include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <string.h>
#include <string>
#include <vector>
#include <queue>
#define MEM(a,x) memset(a,x,sizeof a)
#define eps 1e-8
#define MOD 10009
#define MAXN 200010
#define MAXM 100010
#define INF 99999999
#define ll __int64
#define bug cout<<"here"<<endl
#define fread freopen("ceshi.txt","r",stdin)
#define fwrite freopen("out.txt","w",stdout)
using namespace std;
int Read()
{
char c = getchar();
while (c < '0' || c > '9') c = getchar();
int x = 0;
while (c >= '0' && c <= '9') {
x = x * 10 + c - '0';
c = getchar();
}
return x;
}
void Print(int a)
{
if(a>9)
Print(a/10);
putchar(a%10+'0');
}
struct Edge
{
int to,val,next;
}edge[MAXN];
int head[MAXN],tot;
void init()
{
tot=0;
MEM(head,-1);
}
void addedge(int u,int v,int w)
{
edge[tot].to=v; edge[tot].next=head[u]; edge[tot].val=w; head[u]=tot++;
edge[tot].to=u; edge[tot].next=head[v]; edge[tot].val=w; head[v]=tot++;
}
int n,m;
int vis[MAXN];
int dis[MAXN];
int ans;
void dfs(int u,int fa)//搜索哪些点要走到
{
for(int i=head[u];i!=-1;i=edge[i].next)
{
int v=edge[i].to;
if(v==fa) continue;
dfs(v,u);
if(vis[v])
vis[u]=1;
}
}
void dfs2(int u,int fa)//搜索求距离
{
for(int i=head[u];i!=-1;i=edge[i].next)
{
int v=edge[i].to;
if(v==fa) continue;
dis[v]=dis[u]+edge[i].val;
if(vis[v])
ans+=edge[i].val;
dfs2(v,u);
}
}
int main()
{
// fread;
while(scanf("%d%d",&n,&m)!=EOF)
{
init();
MEM(vis,0);
for(int i=0;i<n-1;i++)
{
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
addedge(u,v,w);
}
for(int i=0;i<m;i++)
{
int v;
scanf("%d",&v);
vis[v]=1;
}
ans=0;
dis[1]=0;
dfs(1,-1);
dfs2(1,-1);
int mx=-1;
for(int i=1;i<=n;i++)
{
// cout<<"ii "<<i<<" dis "<<dis[i]<<endl;
if(vis[i])
mx=max(mx,dis[i]);
}
// cout<<"ans "<<ans<<" "<<"mx "<<mx<<endl;
printf("%d\n",ans-mx);
}
return 0;
}