//对于每个点,求出来距离其最近的k个编号为1点,求其距离和
//反过来求,求每一个编号为1的点到其他所有点的最短距离
//题目中最多有1000个1号点,
//ds[x][1000]:点x到每个1号点的最短距离,从小到大排个序,前k个最短距离相加和
//遍历所有x,求其前k个的和即可
#include<iostream>
#include<algorithm>
#include<cstring>
#include <queue>
using namespace std;
const int N = 10010,M = 10010*2,INF = 0x3f3f3f3f;
int n,m,k;
int type[N],st[N];
int h[N],e[M],ne[M],w[M],idx;
int dist[N],ds[N][1010],cnt;
void add(int a,int b,int c)
{
e[idx] = b,w[idx] = c,ne[idx] = h[a],h[a]=idx++;
}
void spfa(int start)
{
memset(dist,0x3f,sizeof dist);
dist[start] = 0;
queue<int> q;
q.push(start);
st[start] = true;
while(q.size())
{
int t = q.front();
q.pop();
st[t] = false;
for(int i = h[t]; ~i; i = ne[i])
{
int j = e[i];
if(dist[j] > dist[t]+w[i])
{
dist[j] = dist[t]+w[i];
if(!st[j])
{
q.push(j);
st[j] = true;
}
}
}
}
for(int i = 1; i<=n; i++) ds[i][cnt] = dist[i];
}
int main()
{
cin>>n>>m>>k;
memset(h,-1,sizeof h);
for(int i = 1; i<=n; i++) cin>>type[i];
while(m--)
{
int a,b,c;
cin>>a>>b>>c;
add(a,b,c),add(b,a,c);
}
//从所有编号是1里求最短路
for(int i = 1; i<=n; i++)
if(type[i])
{
spfa(i);
cnt++;//cnt表示当前处理到第几个编号为1的点
}
for(int i = 1; i<=n; i++)
{
int res = 0;
sort(ds[i],ds[i]+cnt);
for(int j = 0; j<k && j<cnt; j++)
if(ds[i][j]!=INF) res += ds[i][j];
else break;
cout<<res<<endl;
}
return 0;
}