防爆栈,只要在头文件的前面加上#pragma comment(linker, "/STACK:102400000,102400000")就可以了
/*题意:给一树,每个结点有人数,边有权值,表示经过这条边所需时间,
问取某个结点作为开会地点,所有人全部到达此结点最少所需总时间?
分析:先深搜一次,把以每个结点为根结点的子树的结点数目以及
子树中所有结点到此结点的时间和求出来。然后再利用上面所求的信息,
再深搜一次。对于当前某结点作为最终开会的地点,总时间可分为三种,
第一种是所有父亲结点及以上的点到父亲结点的时间和
第二种是此结点的子树中的结点到此结点的时间和
第三种是父亲及以上的结点与此结点的兄弟结点到此结点的时间和
因为结点太多,直接深搜爆栈,所以要手动模拟。注释部分为直接深搜
*/
#include<stdio.h>
#include<vector>
#include<iostream>
using namespace std;
const __int64 maxn=110000;
__int64 n,minsum,q[maxn],p[maxn],f[maxn],sump[maxn],sum[maxn],sump2[maxn],sum2[maxn];
bool flag[maxn];
struct point
{
__int64 v,w;
}p0;
vector<point>e[maxn];
void DFS1()
{
__int64 i,j,k,top=0;
memset(flag,false,sizeof(flag));
q[top++]=1;
while(top)
{
k=q[top-1];
if(!flag[k])
{
flag[k]=true;
for(i=0;i<e[k].size();i++)
{
j=e[k][i].v;
if(j==f[k]) continue;
f[j]=k;
q[top++]=j;
}
}
else
{
sump[k]=p[k];
for(i=0;i<e[k].size();i++)
{
j=e[k][i].v;
if(j==f[k]) continue;
sump[k]+=sump[j];
sum[k]+=sum[j]+sump[j]*e[k][i].w;
}
top--;
}
}
/* sump[now]=p[now];
for(i=0;i<e[now].size();i++)
{
j=e[now][i].v;
if(j==f) continue;
DFS1(j,now);
sump[now]+=sump[j];//子代结点数目
sum[now]+=sump[j]*e[now][i].w+sum[j];//子代到其时间和
}*/
}
void DFS2()//void DFS2(int now,int f,int sum1,int p1)表示现在在now结点,其父亲为f,除了其父亲为根结点的树中的点到其父亲的的总时间和总结点数
{
__int64 now,i,j,top=0;
memset(flag,false,sizeof(flag));
q[top++]=1;
if(sum[1]<minsum) minsum=sum[1];
while(top)
{
now=q[top-1];
if(!flag[now])
{
flag[now]=true;
for(i=0;i<e[now].size();i++)
{
j=e[now][i].v;
if(j==f[now]) continue;
f[j]=now;
sump2[j]=sump2[now]+sump[now]-sump[j];
sum2[j]=sum2[now]+sum[now]-sum[j]-sump[j]*e[now][i].w+sump2[j]*e[now][i].w;
if(sum[j]+sum2[j]<minsum) minsum=sum[j]+sum2[j];
q[top++]=j;
}
}
else top--;
}
/*i=sum[now]+sum1;
if(i<minsum) minsum=i;
for(i=0;i<e[now].size();i++)
{
j=e[now][i].v;
if(j==f)continue;
DFS2(j,now,sum1+sum[now]-sum[j]-sump[j]*e[now][i].w+(p1+sump[now]-sump[j])*e[now][i].w,p1+sum[now]-sump[j]);
}*/
}
__int64 main()
{
__int64 i,u,v,w;
while(scanf("%I64d",&n)!=EOF)
{
for(i=1;i<=n;i++)
scanf("%I64d",&p[i]);
for(i=0;i<=n;i++)
e[i].clear();
for(i=1;i<n;i++)
{
scanf("%I64d%I64d%I64d",&u,&v,&w);
p0.v=v,p0.w=w;
e[u].push_back(p0);
p0.v=u;
e[v].push_back(p0);
}
memset(f,-1,sizeof(f));
memset(sump,0,sizeof(sump));
memset(sum,0,sizeof(sum));
minsum=0x7fffffffffffffff;
DFS1();
memset(sum2,0,sizeof(sum2));
memset(sump2,0,sizeof(sump2));
DFS2();
printf("%I64d\n",minsum);
}
return 0;
}