• 牛客4370 E Cave Escape (最大生成树)


    题目链接:https://ac.nowcoder.com/acm/contest/4370/E
    每个格子都要尽量与乘积最大的相邻格子连边,最后形成的几个连通块也要连尽可能最大的边
    最后形成了一棵树,也就是最大生成树

    这个题普通写法太慢了,注意到权值最大不超过(10000),于是可以按边的权值开桶,省去排序

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<iostream>
    #include<cmath>
    #include<stack>
    #include<queue>
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> P;
    
    const int maxn = 1010;
    
    int T, N, M, Case, cnt, tot, num; ll ans;
    int X[maxn * maxn], A, B, C, PP, sr, sc, tr, tc;
    int x[maxn * maxn], y[maxn * maxn], id[maxn][maxn], v[maxn][maxn];
    int fa[maxn * maxn],ran[maxn * maxn];
    int dx[4] = {-1, 0};
    int dy[4] = {0, -1};
    
    vector<P> e[10010];
    
    inline void init(){ ans = 0; num = 0; for(int i=1;i<=cnt;++i) fa[i] = i, ran[i] = 1; }
    
    inline int find(int x){ return fa[x] = (fa[x] == x? x: find(fa[x])); }
    
    inline void unite(int x,int y){
    	x = find(x), y = find(y);
    	if(x == y) return;
    	if(ran[x] < ran[y]){
    		fa[x] = y;
    	}else{
    		fa[y] = x;
    		if(ran[x] == ran[y]) ++ran[x];
    	}
    }
    
    inline void kruscal(){
    	init();
    
    	for(int i=10000;i>=0 && num<cnt;--i){
    		for(auto x : e[i]){
    			if(find(x.first) != find(x.second)){
    				++num;
    				unite(x.first,x.second);
    				ans += i;
    			}
    		}
    	}
    }
    
    ll read(){ ll s=0,f=1; char ch=getchar(); while(ch<'0' || ch>'9'){ if(ch=='-') f=-1; ch=getchar(); } while(ch>='0' && ch<='9'){ s=s*10+ch-'0'; ch=getchar(); } return s*f; }
    
    int main(){
    	T = read(); Case = 0;
    	while(T--){
    		++Case;
    		for(int i=10000;i>=0;--i) e[i].clear();
    		cnt = 0; tot = 0;
    		N = read(), M = read(); sr = read(), sc = read(), tr = read(), tc = read();
    		X[1] = read(), X[2] = read(); A = read(), B = read(), C = read(), PP = read();
    		for(int i=3;i<=N*M;++i){ X[i] = (1ll * A * X[i-1] + 1ll * B * X[i-2] + C) % PP; }
    		for(int i=1;i<=N;++i)
    			for(int j=1;j<=M;++j){ 
    				v[i][j] = X[(i-1) * M + j];
    				
    				++cnt;
    				int u1 = (i-1) * M + j - 1, u2 = (i-2) * M + j;
    				if(j!=1) e[v[i][j] * v[i][j-1]].push_back(P(u1,cnt));
    				if(i!=1) e[v[i][j] * v[i-1][j]].push_back(P(u2,cnt));
    			}
    		
    		kruscal();
    		
    		printf("Case #%d: %lld
    ",Case,ans);
    	}
    	return 0;
    }
    
  • 相关阅读:
    模板引擎
    MongoDB基础操作
    node异步编程
    关于bootstrap table 的可编辑列表的实例
    weblogic 补丁步骤
    BIZ中model.getSql源码分析
    windows切换 jdk的坑!!!
    Oracle 给予访问其他用户包的权限
    关于解决Tomcat服务器Connection reset by peer 导致的宕机
    查找多余逗号的正则表达式
  • 原文地址:https://www.cnblogs.com/tuchen/p/13888298.html
Copyright © 2020-2023  润新知