zoukankan      html  css  js  c++  java
  • 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)

    首先把行和列分为左部点和右部点,格子全部涂黑意味着这是一个全连接层每个左部点和所有右部点都有连边且每个右部点和所有左部点都有连边(即完全二部图)。初始情况为所有点都是孤立点。然后就是另一个条件了:对于任何两行两列的四个相交的方块,如果其中三个是黑色方块,则可以不计成本地将第四个方块染成黑色。在这个二分图中这个条件意味着什么呢?设三个黑色方块分别为((r_1,c_1),(r_1,c_2),(r_2,c_1)),那么可以得到((r_2,c_2)),注意到这实际上是不改变整个图的连通分量的个数的(第四条边添加上去以后是一个环),同时,对于每个连通分量也可以通过零成本添加边使其内部每个左部点和所有右部点都有连边且每个右部点和所有左部点都有连边。举个栗子,设现在已经有((6,6),(6,4)),显然满足条件(左部点的6和右部点的6,4都有边且右部点的6、4和左部点的6都有边),再添加一条边((5,6)),画在图上就会发现这个子图也是完全二部图,按照题目的描述就是((5,4),(5,6),(6,4),(6,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;
    }
    
  • 相关阅读:
    Tomcat搭建Web 应用服务器
    前端代码的开发标准和规范
    全局关键字搜索:Element UI Table内容过滤jQuery过滤器fastLiveFilter插件BootstrapVue插件;
    Highchartsjs使用总结及实时动态刷新图
    百度统计微信网站绑定(vue项目)
    对Vuejs框架原理名词解读
    xml
    webservice
    类加载器
    引入spring时 XML文档中的xmlns、xmlns:xsi和xsi:schemaLocation
  • 原文地址:https://www.cnblogs.com/lipoicyclic/p/15058046.html
Copyright © 2011-2022 走看看