牛客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;
}
原文地址:https://www.cnblogs.com/tuchen/p/13888298.html