牛客2021暑期训练3-B-Black and white
题意
给定 n*m 的矩阵,每个小方块有一个被染黑的代价 c[i][j],若四个方块形成矩形,其中一个方块无需代价。求矩阵全部染黑代价的最小值
题解
对于⼀个位置 ,如果该格子是黑色,我们连⼀条 A[i] 到 B[j] 的边。绿色已染,红色未染,所以
A[3]–B[2],
A[5]–B[2],
A[5]–B[6],
当我们要染 (3,6) 时,可以发现 A[3], B[6]已经在一个集合了
显然用最小生成树做就可以了
代码
#include<bits/stdc++.h>
#define LL long long
using namespace std;
const int N=5e3+9;
int n,m,A,B,cnt,tot;
LL ans,a,b,c,d,p;
int f[N*2];
struct node
{
int x,y;
LL z;
node() {}
node(int i,int j,int k) {x=i; y=j; z=k;}
bool operator < (const node &u) const
{
return z<u.z;
}
}t[N*N];
int find(int x)
{
return f[x]==x?x:f[x]=find(f[x]);
}
void Work()
{
for(int i=1;i<=n+m;i++)
f[i]=i;
sort(t+1,t+1+cnt);
for(int i=1;i<=cnt&&tot!=n+m-1;i++)
{
int x=find(t[i].x),y=find(t[i].y+n);
if(x!=y)
{
ans+=t[i].z;
tot++;
f[x]=y;
}
}
}
int main()
{
cin>>n>>m>>a>>b>>c>>d>>p;
while(A<n)
{
A++; B=0;
while(B<m)
{
B++;
a=(a*a*b+a*c+d)%p;
t[++cnt]=(node){A,B,a};
}
}
Work();
cout<<ans<<endl;
return 0;
}