You are given an undirected connected graph consisting of nnn vertices and mmm edges. kkk vertices of this graph are special.
You have to direct each edge of this graph or leave it undirected. If you leave the iii-th edge undirected, you pay wiw_iwi coins, and if you direct it, you don’t have to pay for it.
Let’s call a vertex saturated if it is reachable from each special vertex along the edges of the graph (if an edge is undirected, it can be traversed in both directions). After you direct the edges of the graph (possibly leaving some of them undirected), you receive ci coins for each saturated vertex iii. Thus, your total profit can be calculated as ∑i∈Sci−∑j∈Uwj∑\limits_{i∈S}c_i−∑\limits_{j∈U}w_ji∈S∑ci−j∈U∑wj, where SSS is the set of saturated vertices, and UUU is the set of edges you leave undirected.
For each vertex iii, calculate the maximum possible profit you can get if you have to make the vertex iii saturated.
Input
The first line contains three integers nnn, mmm and kkk (2≤n≤3⋅105,n−1≤m≤min(3⋅105,n(n−1)2),1≤k≤n)(2≤n≤3⋅10^5, n−1≤m≤min(3⋅10^5,\frac{n(n−1)}{2}), 1≤k≤n)(2≤n≤3⋅105,n−1≤m≤min(3⋅105,2n(n−1)),1≤k≤n).
The second line contains kkk pairwise distinct integers v1,v2,…,vkv_1, v_2, \dots, v_kv1,v2,…,vk (1≤vi≤n)(1≤v_i≤n)(1≤vi≤n) — the indices of the special vertices.
The third line contains nnn integers c1,c2,…,cnc_1, c_2, \dots, c_nc1,c2,…,cn (0≤ci≤109)(0≤c_i≤10^9)(0≤ci≤109).
The fourth line contains mmm integers w1,w2,…,wmw_1, w_2, \dots, w_mw1,w2,…,wm (0≤wi≤109)(0≤w_i≤10^9)(0≤wi≤109).
Then mmm lines follow, the iii-th line contains two integers xix_ixi and yiy_iyi (1≤xi,yi≤n,xi≠yi)(1≤x_i,y_i≤n, x_i≠y_i)(1≤xi,yi≤n,xi=yi) — the endpoints of the iii-th edge.
There is at most one edge between each pair of vertices.
Output
Print nnn integers, where the iii-th integer is the maximum profit you can get if you have to make the vertex iii saturated.
Examples
input
3 2 2
1 3
11 1 5
10 10
1 2
2 3
output
11 2 5
input
4 4 4
1 2 3 4
1 5 7 8
100 100 100 100
1 2
2 3
3 4
1 4
output
21 21 21 21
Note
Consider the first example:
the best way to make vertex 111 saturated is to direct the edges as 2→1,3→22→1, 3→22→1,3→2; 111 is the only saturated vertex, so the answer is 111111;
the best way to make vertex 222 saturated is to leave the edge 1−21−21−2 undirected and direct the other edge as 3→23→23→2; 111 and 222 are the saturated vertices, and the cost to leave the edge 1−21−21−2 undirected is 101010, so the answer is 222;
the best way to make vertex 333 saturated is to direct the edges as 2→32→32→3, 1→21→21→2; 333 is the only saturated vertex, so the answer is 555.
The best course of action in the second example is to direct the edges along the cycle: 1→2,2→3,3→41→2, 2→3, 3→41→2,2→3,3→4 and 4→14→14→1. That way, all vertices are saturated.
首先,对于一个边双连通分量,由于任意两点之间至少存在两条边不重复路径,因此可以通过将其所有边修改为有向边使其成为一个强连通分量。对于一个强连通分量,只要其中一个点饱和,则其余点都饱和,因此可以进行e−DCCe-DCCe−DCC缩点,将其转化为树上问题。
缩点后,以某个关键节所在点为根,如果以某个点为根的子树中不含关键节点,则这棵子树无需向外连边,即子树上的所有点都只连一条到子节点的有向边即可,不需要花费连无向边的费用,因此可以将该子树上的点全部合并到根节点的父节点上。最终构造出来的树的根节点和所有叶子节点都含关键节点。
这里解释一下为什么要以某个关键节所在点为根:因为在后面树形dpdpdp的时候首先默认了对于当前dpdpdp的点,其子树上所有点都能到达它,而不含关键节点的点不需要其他点都能到达它如果加反边会增加不必要的花费,结果不是最优。
设边双连通分量SSS缩点为xxx,则val[x]=∑i∈Sc[i]val[x]=\sum\limits_{i∈S}c[i]val[x]=i∈S∑c[i]。
设f[x]f[x]f[x]为以xxx为根的子树中如果饱和点包含xxx,那么最大收益为f[x]f[x]f[x]。
这里的饱和点的含义是:如果xxx为根节点则所有以xxx为根的子树中所有的关键节点都能到达该点,否则xxx为整个树上的饱和点,但是算收益时只减去子树内的边(后面转移的时候会考虑上其余边)。
状态转移方程为:
f[x]=val[x]+∑y∈sonmax(0,f[y]−wx,y)f[x]=val[x]+\sum_{y\in son}\max(0,f[y]-w_{x,y}) f[x]=val[x]+y∈son∑max(0,f[y]−wx,y)
状态转移方程的含义为首先假设子树上的所有点都能到达xxx,那么xxx为饱和点,此时收益为val[x]val[x]val[x] ,如果对于子节点yyy,如果以yyy为根的子树中的一些点也想成为饱和点,那么需要在当前收益上加上f[y]−wx,yf[y]-w_{x,y}f[y]−wx,y,考虑到最大收益,因此只加为正的时候的,即 max(0,f[y]−wx,y)\max(0,f[y]-w_{x,y})max(0,f[y]−wx,y)。
最终f[root]f[root]f[root]为保证根节点是饱和点时的最大收益。
由于题目中要求求出对于每个点,保证该点为饱和点时的最大收益,因此还需要进行换根dpdpdp。
状态转移方程为:
f[y]=f[y]+max(0,f[x]−max(0,f[y]−wx,y)−wx,y)f[y]=f[y]+\max (0,f[x]-\max (0,f[y]-w_{x,y})-w_{x,y})f[y]=f[y]+max(0,f[x]−max(0,f[y]−wx,y)−wx,y)
这里xxx为yyy的父节点。保证yyy点为饱和点时的最大收益,为以yyy为根节点时的最大收益加上父节点xxx对f[y]f[y]f[y]的贡献再减去wx,yw_{x,y}wx,y,即max(0,f[x]−max(0,f[y]−wx,y)−wx,y)\max (0,f[x]-\max (0,f[y]-w_{x,y})-w_{x,y})max(0,f[x]−max(0,f[y]−wx,y)−wx,y)。而父节点xxx对f[y]f[y]f[y]的贡献为保证xxx点为饱和点时的最大收益减去以yyy为根的子树对其的贡献,即max(0,f[y]−wx,y)−wx,y\max (0,f[y]-w_{x,y})-w_{x,y}max(0,f[y]−wx,y)−wx,y。
时间复杂度为O(n)O(n)O(n)。
#include<bits/stdc++.h>
#define repi(i, a, b) for(register int i=a;i<=b;++i)
#define ll long long
#define ce(i, r) i==r?'\n':' '
using namespace std;
inline int qr() {
int f = 0, fu = 1;
char c = getchar();
while (c < '0' || c > '9') {
if (c == '-')fu = -1;
c = getchar();
}
while (c >= '0' && c <= '9') {
f = (f << 3) + (f << 1) + c - 48;
c = getchar();
}
return f * fu;
}
const int N = 3e5 + 10, M = 3e5 + 10;
int head[N], ver[M << 1], Next[M << 1], edge[M << 1], tot = 1;
int hc[N], vc[M << 1], nc[M << 1], ec[M << 1], tc, dcc;
int n, m, k;
inline void add(int x, int y, int z) {
ver[++tot] = y;
Next[tot] = head[x];
edge[tot] = z;
head[x] = tot;
}
struct E_DCC {
int dfn[N], low[N], c[N];
int num;
bool bridge[M << 1];
void tarjan(int x, int in_edge) {
dfn[x] = low[x] = ++num;
for (int i = head[x]; i; i = Next[i]) {
int y = ver[i];
if (!dfn[y]) {
tarjan(y, i);
low[x] = min(low[x], low[y]);
if (low[y] > dfn[x])
bridge[i] = bridge[i ^ 1] = true;
} else if (i != (in_edge ^ 1))
low[x] = min(low[x], dfn[y]);
}
}
inline void solve() {
repi(i, 1, n)if (!dfn[i])tarjan(i, 0);
e_dcc(), build();
}
void dfs(int x) {
c[x] = dcc;
for (int i = head[x]; i; i = Next[i]) {
int y = ver[i];
if (c[y] || bridge[i]) continue;
dfs(y);
}
}
inline void e_dcc() {
dcc = 0;
repi(i, 1, n)if (!c[i])++dcc, dfs(i);
}
void add_c(int x, int y, int z) {
vc[++tc] = y, nc[tc] = hc[x], ec[tc] = z, hc[x] = tc;
}
inline void build() {
repi(i, 1, n)hc[i] = 0;
tc = 1;
repi(i, 2, tot) {
int x = ver[i ^ 1], y = ver[i], z = edge[i];
if (c[x] == c[y]) continue;
add_c(c[x], c[y], z);
}
}
} E;
int c[N], w[M], v[N], top[N];
ll val[N], f[N];
bool key[N];
void dfs1(int x, int fa) {
for (int i = hc[x]; i; i = nc[i]) {
int y = vc[i];
if (y == fa)continue;
dfs1(y, x), key[x] |= key[y];
}
}
void dfs2(int x, int fa) {
top[x] = key[x] ? x : top[fa];
for (int i = hc[x]; i; i = nc[i]) {
int y = vc[i];
if (y == fa)continue;
dfs2(y, x);
}
}
void dfs3(int x, int fa) {
f[x] = val[x];
for (int i = hc[x]; i; i = nc[i]) {
int y = vc[i], z = ec[i];
if (y == fa || !key[y])continue;
dfs3(y, x), f[x] += max(0ll, f[y] - z);
}
}
void dfs4(int x, int fa) {
for (int i = hc[x]; i; i = nc[i]) {
int y = vc[i], z = ec[i];
if (y == fa || !key[y])continue;
f[y] += max(0ll, f[x] - max(0ll, f[y] - z) - z), dfs4(y, x);
}
}
int main() {
n = qr(), m = qr(), k = qr();
repi(i, 1, k)v[i] = qr();
repi(i, 1, n)c[i] = qr();
repi(i, 1, m)w[i] = qr();
repi(i, 1, m) {
int x = qr(), y = qr();
add(x, y, w[i]), add(y, x, w[i]);
}
E.solve();
repi(i, 1, n)val[E.c[i]] += c[i];
repi(i, 1, k)key[E.c[v[i]]] = true;
int r = E.c[v[1]];
dfs1(r, 0), dfs2(r, 0);
repi(i, 1, dcc)if (!key[i])val[top[i]] += val[i];
repi(i, 1, n)E.c[i] = top[E.c[i]];
dfs3(r, 0), dfs4(r, 0);
repi(i, 1, n)printf("%lld%c", f[E.c[i]], ce(i, n));
return 0;
}