答案肯定为 一种颜色联通块 和 另一种颜色联通块 的 并 的大小,
且 并 中存在 “一座桥”, 可以让其中一个颜色通过, 联通两个联通块 .
于是考虑先预处理出每个颜色的所有联通块的大小, 给每个不同的联通块分配一个编号, 大小记为 ,
对一个询问 , 考虑求出 所处的 种颜色联通块与其他颜色 最大 的 并, 设为 ,
则对一个点, 它 属于 它所在的 其中一个颜色联通块 和 另一个颜色联通块 的 交,
所以枚举每个点, 使用这个点的权值去计算出每个联通块之间的 交, 记为 , 可以使用 std::map<int, ll> intv[]
存储 .
接下来枚举开头提到的那座 “桥” , 再枚举两边联通块的颜色, 分别记为
在满足 这座 “桥” 允许其中一种颜色通过 的前提下, 使用 更新 所在的对应联通块的答案 .
最后询问时, 枚举当前点的 种颜色的联通块, 取其中最大的 作为答案即可 .
#include<bits/stdc++.h>
#define reg register
typedef long long ll;
int read(){
char c;
int s = 0, flag = 1;
while((c=getchar()) && !isdigit(c))
if(c == '-'){ flag = -1, c = getchar(); break ; }
while(isdigit(c)) s = s*10 + c-'0', c = getchar();
return s * flag;
}
const int maxn = 100005;
int N;
int M;
int num0;
int Id_cnt;
int A[maxn];
int head[maxn];
int vis[maxn][4];
ll size[maxn];
ll max_v[maxn];
std::map <int, ll> intv[maxn];
struct EDGE{ int u, v, w; } E[maxn];
struct Edge{ int nxt, to, w; } edge[maxn << 1];
void Add(int from, int to, int w){ edge[++ num0] = (Edge){ head[from], to, w }; head[from] = num0; }
void DFS(int k, const int &col, const int &id){
vis[k][col] = id, size[id] += A[k];
for(reg int i = head[k]; i; i = edge[i].nxt){
int to = edge[i].to;
if(col == edge[i].w || vis[to][col]) continue ;
DFS(to, col, id);
}
}
void Work(){
ll Ans = 0; int x = read();
for(reg int col = 1; col <= 3; col ++) Ans = std::max(Ans, max_v[vis[x][col]]);
printf("%lld
", Ans);
}
int main(){
N = read(), M = read();
for(reg int i = 1; i <= N; i ++) A[i] = read();
for(reg int i = 1; i <= M; i ++){
E[i].u = read(), E[i].v = read(), E[i].w = read();
Add(E[i].u, E[i].v, E[i].w), Add(E[i].v, E[i].u, E[i].w);
}
for(reg int col = 1; col <= 3; col ++)
for(reg int j = 1; j <= N; j ++)
if(!vis[j][col]) DFS(j, col, ++Id_cnt);
for(reg int i = 1; i <= N; i ++)
for(reg int j = 3; j >= 1; j --)
for(reg int k = j-1; k >= 1; k --)
intv[vis[i][j]][vis[i][k]] += A[i], intv[vis[i][k]][vis[i][j]] += A[i];
for(reg int i = 1; i <= M; i ++){
if(vis[E[i].u][E[i].w] == vis[E[i].v][E[i].w]) continue ;
for(reg int col = 1; col <= 3; col ++){
if(E[i].w == col) continue ;
int x = vis[E[i].u][E[i].w], y = vis[E[i].v][col];
max_v[x] = std::max(max_v[x], size[x] + size[y] - intv[x][y]);
max_v[y] = std::max(max_v[y], size[x] + size[y] - intv[x][y]);
x = vis[E[i].v][E[i].w], y = vis[E[i].u][col];
max_v[x] = std::max(max_v[x], size[x] + size[y] - intv[x][y]);
max_v[y] = std::max(max_v[y], size[x] + size[y] - intv[x][y]);
}
}
int Q_ = read();
while(Q_ --) Work();
return 0;
}