Meaning of the questions:
A \ (n-\) nodes of the tree, above \ (K \) key points, through each side requires a certain weight, seeking \ ([1, n] \ ) from each starting point, after all key points, not back to square one, through which the path of minimum weight and value.
data range:
50 minutes: \ (O (^ n-2) \)
Finally, consider the return to the source case, then each is a need to go side to go through twice, no matter how you go all the same. And so only the requirements, and the current source to a certain critical point of the longest path, to subtract (minus the last back away) need to go all sides.
A current source to a key point of the longest path well ask, \ (the DFS \) just once.
As shown, the blue dot to the current source, the red dot keys.
The so-called need to take sides, that is rough edges in the graph can be found by observing, as a side rough edges, if and only if the subtree this edge connection sons have key points .
So just find the key points in each sub-tree when each source point to the \ (cnt \) , to traverse time statistics about enough. Time complexity \ (O (n ^ 2) \)
Key Code:
struct cut1{
int s[2005],dp[2005],mark[2005],suml,mx;
void dfs(int x,int f,int d){
if(mark[x]&&d>mx)mx=d;//求最长路径
if(mark[x])dp[x]=1;
for(int i=0;i<edge[x].size();i++){
int y=edge[x][i].to,z=edge[x][i].v;
if(y==f)continue;
dfs(y,x,d+z);
if(dp[y]!=0)suml+=z;//统计所有要走到的边
dp[x]+=dp[y];
}
}
void solve(){
for(int i=1,x;i<=k;i++){
scanf("%d",&x);//输入关键点
mark[x]=1;
}
for(int i=1;i<=n;i++){
memset(dp,0,sizeof(dp));
suml=0;mx=0;
dfs(i,0,0);
printf("%d\n",suml*2-mx);
}
}
}P50;
100: \ (O (m) \) from the idea of extending from 50 minutes
And 50 points, will have two major problems:
Each point is determined to a certain critical point of a longest path
Each point is determined to be traversed through the edge (edge and crude)
For the second question , a solution to a problem already explained very well. . .
Defined in \ (X \) is the rough edges and root to \ (SUM [X] \) , \ (Y \) is the \ (X \) son, discussion can be divided into the following three categories:
Specific details can reference code.
As to the first question, I heard very classic,I have not heard, The idea is that the tree DP
Under each node in mind it to its critical point of the path subtree maximum value and the time length value .
This is better achieved, once \ (dfs \) can be.
Note: The maximum value and Minister value is not in the strict sense, but for each node, from its two different sons came in. It will explain the specific reasons behind.
We longest path point to a critical point of discussion into two parts: the outer key of the key points in the sub-tree and the subtrees.
Separately, see the code:
#include<bits/stdc++.h>
#define debug(a) cout<<#a<<"="<<a<<endl
#define LL long long
using namespace std;
bool cur1;
const LL N=500005,inf=1e9;
struct node{LL to,v;};
vector<node>edge[N];
LL n,K;
LL mx[N][2],mxf[N],cnt[N],sum[N],tmx[N],st[N],top,fa[N],mark[N];
void dfs(LL x,LL f){
fa[x]=f;mx[x][0]=mx[x][1]=mxf[x]=-inf;
if(mark[x]){
mx[x][0]=0;
cnt[x]=1;
}
st[++top]=x;
for(LL i=0;i<edge[x].size();i++){
LL y=edge[x][i].to,z=edge[x][i].v;
if(y==f)continue;
dfs(y,x);
cnt[x]+=cnt[y];
if(cnt[y]){
sum[1]+=z;
LL nw=mx[y][0]+z;
if(nw>=mx[x][0]){
tmx[x]=y;
mx[x][1]=mx[x][0];
mx[x][0]=nw;
}
else if(nw>mx[x][1])mx[x][1]=nw;
}
}
}
void solve(){
for(LL i=1;i<=n;i++){
LL x=st[i];
for(LL j=0;j<edge[x].size();j++){
LL y=edge[x][j].to,z=edge[x][j].v;
if(y==fa[x])continue;
if(cnt[y]==K)sum[y]=sum[x]-z;
else if(cnt[y]==0)sum[y]=sum[x]+z;
else sum[y]=sum[x];
if(tmx[x]==y)mxf[y]=max(mxf[x],mx[x][1])+z;
else mxf[y]=max(mxf[x],mx[x][0])+z;
}
}
for(LL i=1;i<=n;i++)
printf("%lld\n",sum[i]*2-max(mxf[i],mx[i][0]));
}
bool cur2;
int main(){
scanf("%lld%lld",&n,&K);
for(LL i=1,x,y,z;i<n;i++){
scanf("%lld%lld%lld",&x,&y,&z);
edge[x].push_back(node<%y,z%>);
edge[y].push_back(node<%x,z%>);
}
for(LL i=1,x;i<=K;i++){
scanf("%lld",&x);
mark[x]=1;
}
dfs(1,0);
solve();
return 0;
}