题目
思路
代码
好像ubuntu里写的代码,在win下面就wa了而且还会出现乱码注释。。。
注意INF定为1e18!输出在win下是I64d,不然只能拿到50分!
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#define MAXN 1000010
#define INF 1e18
using namespace std;
typedef long long int LL;
struct edge
{
int u,v,next;
}edges[MAXN*2];
int head[MAXN],nCount=0;
void AddEdge(int U,int V)
{
edges[++nCount].u=U;
edges[nCount].v=V;
edges[nCount].next=head[U];
head[U]=nCount;
}
//size[u]=瀛愭爲u澶у皬锛宯um[u]=缁撶偣u涓婄殑娲鹃仯娆℃暟锛宻um[u]=缁撶偣u涓婁竴鍏辨淳閬g殑澹叺涓暟
LL size[MAXN],num[MAXN],sum[MAXN],f[MAXN],g[MAXN]; //f[u]=浠涓烘牴鐨勫瓙鏍戜腑锛岃嫢u娲?涓汉锛寀鐨勫効瀛愭淳2浜猴紝瀛欏瓙娲?浜?..瀛愭爲u涓淳閬e+鍏垫€诲拰銆俫[u]=浠涓烘牴鐨勫瓙鏍戜腑娲鹃仯鐨勫+鍏垫€诲拰
int n,m;
LL ans[MAXN]; //ans[i]=灏嗙偣i浣滀负鏍硅妭鐐圭殑娲鹃仯澹叺鎬绘暟
void DFS1(int u,int fa)
{
size[u]=1,f[u]=0,g[u]=0;
for(int p=head[u];p!=-1;p=edges[p].next)
{
int v=edges[p].v;
if(v==fa) continue;
DFS1(v,u);
size[u]+=size[v];
f[u]+=f[v]+size[v];
g[u]+=g[v];
}
g[u]+=f[u]*num[u]+sum[u]*size[u];
}
void DFS2(int u,int fa)
{
ans[u]=g[u];
for(int p=head[u];p!=-1;p=edges[p].next)
{
int v=edges[p].v;
if(v==fa) continue;
//鏀瑰彉鏈夊悜鏍戠粨鏋勶紝灏唙浣滀负u鐖朵翰锛屽厛鏇存柊u閲屽叧浜巚鐨勬墍鏈夊€?
g[u]-=f[u]*num[u]+sum[u]*size[u]; //閲嶇疆g[u]
g[u]-=g[v];
size[u]-=size[v];
f[u]-=f[v]+size[v];
g[u]+=f[u]*num[u]+sum[u]*size[u];
//鍐嶆洿鏂皏閲屽叧浜巙鐨勬墍鏈夊€?
g[v]-=f[v]*num[v]+sum[v]*size[v];
size[v]+=size[u];
f[v]+=f[u]+size[u];
g[v]+=g[u];
g[v]+=f[v]*num[v]+sum[v]*size[v];
DFS2(v,u);
//鏀瑰彉鏈夊悜鏍戠粨鏋勶紝灏唘浣滀负v鐖朵翰锛屽厛鏇存柊v閲屽叧浜巙鐨勬墍鏈夊€?
g[v]-=f[v]*num[v]+sum[v]*size[v];
size[v]-=size[u];
f[v]-=f[u]+size[u];
g[v]-=g[u];
g[v]+=f[v]*num[v]+sum[v]*size[v];
//鍐嶆洿鏂皍閲屽叧浜巚鐨勬墍鏈夊€?
g[u]-=f[u]*num[u]+sum[u]*size[u]; //閲嶇疆g[u]
g[u]+=g[v];
size[u]+=size[v];
f[u]+=f[v]+size[v];
g[u]+=f[u]*num[u]+sum[u]*size[u];
}
}
int stack[MAXN],top=0;
int main()
{
freopen("B.in","r",stdin);
freopen("B.out","w",stdout);
memset(head,-1,sizeof(head));
scanf("%d%d",&n,&m);
for(int i=1;i<n;i++)
{
int u,v;
scanf("%d%d",&u,&v);
AddEdge(u,v);
AddEdge(v,u);
}
for(int i=1;i<=m;i++)
{
int pos,val;
scanf("%d%d",&pos,&val);
num[pos]++,sum[pos]+=(LL)val;
}
DFS1(1,-1);
DFS2(1,-1);
LL minans=INF;
for(int i=1;i<=n;i++)
if(ans[i]<minans)
minans=ans[i];
for(int i=1;i<=n;i++)
if(ans[i]==minans)
stack[++top]=i;
printf("%I64d\n",minans);
for(int i=1;i<=top;i++)
printf("%d ",stack[i]);
printf("\n");
return 0;
}