2021牛客暑期多校训练营3 B. Black and white(二分图/最小生成树)
链接:https://ac.nowcoder.com/acm/contest/11254/B
来源:牛客网
题目描述
Goodeat has a white chessboard with n rows and m columns.
Each grid (i, j) has a weight c(i, j). At any time, the grid (i, j) can be dyed black at the cost of c(i, j).
Goodeat has a special talent. For the four intersecting squares of any two rows and two columns, if three of them are black squares, Goodeat can dye the fourth square black without any cost.
Please find out the minimum cost of dyeing a black chessboard.
Due to the large number of grids, we use the following method to generate weights:
A0 = a
A(i+1) = (Ai * Ai * b + Ai * c + d)% p
Where A(m*(i-1)+j) is the cost c(i, j) of the grid in the i-th row and j-th column (1≤i≤n,1≤j≤m)(1≤i≤n,1≤j≤m).
输入描述:
The first line contains seven integers n,m,a,b,c,d,p.(a,b,c,d<p≤100000,n,m≤5000a,b,c,d<p≤100000,n,m≤5000)
输出描述:
Output a single integer denoting the answer.
示例1
输入
复制
4 4 1 2 3 4 7
输出
复制
20
说明
Here is the weight matrix:
2 4 6 3
3 3 3 3
3 3 3 3
3 3 3 3
二分图的套路没想到...还是做题做少了...这个题和CF1012B Chemical table类似(洛谷P5089的EJOI的D)
首先把行和列分为左部点和右部点,格子全部涂黑意味着这是一个全连接层每个左部点和所有右部点都有连边且每个右部点和所有左部点都有连边(即完全二部图)。初始情况为所有点都是孤立点。然后就是另一个条件了:对于任何两行两列的四个相交的方块,如果其中三个是黑色方块,则可以不计成本地将第四个方块染成黑色。在这个二分图中这个条件意味着什么呢?设三个黑色方块分别为,那么可以得到,注意到这实际上是不改变整个图的连通分量的个数的(第四条边添加上去以后是一个环),同时,对于每个连通分量也可以通过零成本添加边使其内部每个左部点和所有右部点都有连边且每个右部点和所有左部点都有连边。举个栗子,设现在已经有,显然满足条件(左部点的6和右部点的6,4都有边且右部点的6、4和左部点的6都有边),再添加一条边,画在图上就会发现这个子图也是完全二部图,按照题目的描述就是是两行两列四个相交的方块,可以自己手动构造一个连通分量然后模拟一下使用魔法加边的情况。这样问题就转化成了花费最小的代价使这个二部图连通,就转化成了最小生成树问题。看数据规模可以使用prim算法或者桶排序的kruskal算法。
#include <bits/stdc++.h>
#define N 5005
using namespace std;
signed fa[100005];
int n,m,a,b,c,d,p;
struct edge {
int x, y, z;
} e[5005 * 5005];
vector<edge> v[1000005];
int get(int x) {
if(x == fa[x]) return x;
return fa[x] = get(fa[x]);
}
signed main() {
cin >> n >> m >> a >> b >> c >> d >> p;
int A = a;
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= m; j++) {
long long tmp = (1ll * A * A * b + 1ll * A * c + 1ll * d) % p;
edge ee;
ee.x = i, ee.y = j + n, ee.z = (int)tmp;
v[ee.z].push_back(ee);
A = tmp;
}
}
for(int i = 1; i <= 10000; i++) {
fa[i] = i;
}
int cnt = 1;
long long ans = 0;
for(int i = 0; i <= 1000000; i++) {
for(auto e:v[i]) {
if(cnt == n + m) break;
int x = e.x, y = e.y, z = e.z;
int fx = get(x), fy = get(y);
if(fx == fy) continue;
cnt++;
ans += 1ll * z;
fa[fx] = fy;
}
}
cout << ans;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
2020-07-25 深度学习笔记一