题意
给你一个 n ∗ m n*m n∗m的矩阵,每个矩阵有一个权值,当一个正方形中三个点均已涂黑后,第四个点可免费涂黑,问将所有点涂黑所需的最小花费。
分析
所有点涂黑相当于将每行和每列均相连, c [ i ] [ j ] = w c[i][j]=w c[i][j]=w相当于从 i i i行走到 j j j列所花费权值为 w w w,建图跑 p r i m prim prim最小生成树即可。
代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int N = 1e5 + 10;
int n, m, a, b, c, d, p;
vector<pii> G[N];
int f[2*N], cnt;
int find(int x){
return f[x] == x ? f[x] : f[x] = find(f[x]);
}
int main(){
ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
cin>>n>>m>>a>>b>>c>>d>>p;
ll val = a;
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++){
val = (val*val*b + val*c+d) % p;
G[val].push_back({i, j+n});
}
for(int i = 0; i <= n + m; i++) f[i] = i;
ll ans = 0;
for(int w = 0; w < N; w++){
for(auto i : G[w]){
int u = find(i.first), v = find(i.second);
if(u == v) continue;
cnt++;
f[u] = v;
ans += w;
if(cnt == n + m - 1){
cout<<ans<<endl;
return 0;
}
}
}
}
赛中根本没想到最小生成树。。。。。
与签到题太毒瘤有很大关系!