输入样例:
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来自清远学会