
输入样例:
3 5 10 5 4 10 8 1 10 1 3 1 4 1 5 1 3 2 1 2 5 4 3 4 3 4 5 5 1 1 4 4 6 1 9 4 7 2 9 5 10 5 2 8 8 10 10 2 1 2 3 3 2 3 4 3 1 3 2 3 4 4 1 5 4 5 1 1 4 2 3 4 7 3 10 1 5 5 10 5 9 9 8 2 1 1 5 1 5 2 1 2 4 2 4 2 4 3 2 3 1 4 3 4 3 5 9 3 9 2 7 5 1 5 4
输出样例:
40 60 90 70 90 8 30 70 100 10 9 81 63 1 4
数据范围:

思路:
让求和一个点联通的所有点的最大值
正解是tarjan,但是可以贪心,建反向边,从大到小排序一下,从最大的那个点宽搜,能扫到的更新他的值为起点的值(也就是这个点联通的最大值),把所有点更新后跳出,每次讯问时查询即可。。。。
注意标号在排序后会改变,另开个数组记录排序前每个标号对应的权值;
dfs bfs 都可以。。。。
多组询问,注意每次数组清零。。。
代码:
bfs:
#include<cstdio>
#include<bits/stdc++.h>
#define MAXN 1000000
using namespace std;
int cnt,head[MAXN],T,n,m,k,ans[MAXN],tot,num[MAXN],pos,cnt1[MAXN];
int val[MAXN];
bool v[MAXN];
struct node{int to,nxt;}e[MAXN<<1];
struct node2{int val,id;}ee[MAXN<<1];
void add(int from,int to)
{
e[++cnt].to=to;
e[cnt].nxt=head[from];
head[from]=cnt;
}
queue <int> q;
bool cmp(const node2 &a,const node2 &b) {return a.val>b.val;}
void bfs(int u)
{
q.push(u);
v[u]=1;
pos++;
while(!q.empty())
{
int x=q.front();
q.pop();
for(int i=head[x] ; i ; i=e[i].nxt)
{
int y=e[i].to;
if(!v[y])
{
pos++;
val[y]=val[u];
v[y]=1;
q.push(y);
}
}
}
}
void init()
{
scanf("%d%d%d",&n,&m,&k);
for(int i=1;i<=n;i++)
{
scanf("%d",&ee[i].val);
val[i]=ee[i].val;
ee[i].id=i;
}
sort(ee+1,ee+n+1,cmp);
for(int i=1;i<=n;i++)num[i]=ee[i].id;
for(int i=1;i<=m;i++)
{
int x,y;
scanf("%d%d",&x,&y);
add(y,x);
}
for(int i=1;i<=n;i++)
{
if(!v[num[i]])bfs(num[i]);
}
int a,u;
for(int i=1;i<=k;i++)
{
scanf("%d%d",&a,&u);
ans[++tot]=val[a]*u;
}
}
void clear()
{
memset(head,0,sizeof(head));
memset(e,0,sizeof(e));
memset(ee,0,sizeof(ee));
memset(v,0,sizeof(v));
memset(num,0,sizeof(num));
memset(val,0,sizeof(val));
}
int main()
{
#ifdef yilnr
#else
freopen("neural.in","r",stdin);
freopen("neural.out","w",stdout);
#endif
scanf("%d",&T);
while(T--)
{
init();
for(int i=1;i<=k;i++) printf("%d
",ans[i]);
clear();
tot=0;pos=0;
}
fclose(stdin);fclose(stdout);
return 0;
}
dfs:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#define N 400500
using namespace std;
inline int read() {
int x = 0,f = 1;
char s = getchar();
while(s < '0' || s > '9') {if(s == '-') f = -1;s = getchar();}
while(s >= '0' && s <= '9') {x = x * 10 + s - '0';s = getchar();}
return x * f;
}
int T,n,m,k;
int head[N],cnt;
struct node {
int nxt,to;
}e[N];
bool vis[N];
struct edge {
int num,id;
bool friend operator < (const edge &a,const edge &b) {
return a.num > b.num;
}
}tr[N];
long long sum[N];
inline void cp(int u,int v) {
cnt ++;
e[cnt].to = v;
e[cnt].nxt = head[u];
head[u] = cnt;
}
inline void dfs(int u,int top) {
vis[u] = 1;
for(int i = head[u]; i ; i = e[i].nxt) {
int v = e[i].to;
if(vis[v]) continue;
sum[v] = sum[top];
dfs(v,top);
}
}
inline void Work() {
n = read(),m = read(),k = read();
for(int i = 1;i <= n;i ++) tr[i].num = read(),tr[i].id = i,sum[i] = tr[i].num;
for(int i = 1;i <= m;i ++) {
int a = read(),b = read();
cp(b,a);
}
sort(tr + 1,tr + n + 1);
for(int i = 1;i <= n;i ++)
if(!vis[tr[i].id]) dfs(tr[i].id,tr[i].id);
for(int i = 1;i <= k;i ++) {
int a = read(),b = read();
printf("%lld
",sum[a] * b);
}
}
inline void Clean() {
memset(sum,0,sizeof(sum));
memset(tr,0,sizeof(tr)); cnt = 0;
memset(head,0,sizeof(head));
memset(vis,0,sizeof(vis));
}
int main() {
freopen("neural.in","r",stdin);
freopen("neural.out","w",stdout);
T = read();
while(T --)
Work(),Clean();
return 0;
}
dfs来自清远学会