• 清北学堂-贪心-bfs


    输入样例:

    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来自清远学会

  • 相关阅读:
    架构的上层是系统,是系统要素的组织形式
    计数与方法论、哲学
    网络编程--会话层、表示层、应用层
    面向中间件编程--草稿
    泛型:基于类型组合的算法和结构构建---数据结构与算法
    面向对象:消息机制更适合描述;
    类型的连接:实连接、虚连接
    数据库 = filesystem + transcation + dsl + dslengine
    一文看透浏览器架构
    代码的结合性:继承 扩展 组合 变换--swift暗含的四根主线
  • 原文地址:https://www.cnblogs.com/yelir/p/11360478.html
Copyright © 2020-2023  润新知