zoukankan      html  css  js  c++  java
  • 【bzoj4883】[Lydsy2017年5月月赛]棋盘上的守卫 最小环套树森林

    题目描述

    在一个n*m的棋盘上要放置若干个守卫。对于n行来说,每行必须恰好放置一个横向守卫;同理对于m列来说,每列必须恰好放置一个纵向守卫。每个位置放置守卫的代价是不一样的,且每个位置最多只能放置一个守卫,一个守卫不能同时兼顾行列的防御。请计算控制整个棋盘的最小代价。

    输入

    第一行包含两个正整数n,m(2<=n,m<=100000,n*m<=100000),分别表示棋盘的行数与列数。
    接下来n行,每行m个正整数
    其中第i行第j列的数w[i][j](1<=w[i][j]<=10^9)表示在第i行第j列放置守卫的代价。

    输出

    输出一行一个整数,即占领棋盘的最小代价。

    样例输入

    3 4
    1 3 10 8
    2 1 9 2
    6 7 4 6

    样例输出

    19


    题解

    最小环套树森林

    首先一眼费用流,然而数据量过大直接卡掉(同时卡掉的还有zkw费用流= =)(跪烂那些用KM算法水过的dalao。。。)

    然后经过观察可以发现,如果在行列之间连边,那么答案构成的一定是一个环套树森林。

    证明:设行数+列数为n,则构成的图中,点数和边数都为n。如果把每条边选择的方案看作是边的方向的话(a/b中选a看作a->b),那么每个点的出度一定均为1。这样的图一定是环套树森林。因此命题得证。

    然后要求的就是无向图的最小环套树森林。

    很容易发现环套树森林也是一个拟阵,拟阵最优化问题即可使用贪心算法(Kruscal)求解。

    那么本题就和求最小生成树的方法一样了,按边权排序,从小到大加。只需要在原并查集的基础之上,维护每个连通块是否有环,连边时判断即可。

    时间复杂度$O(nmlog nm)$

    #include <cstdio>
    #include <algorithm>
    #define N 100010
    using namespace std;
    struct data
    {
    	int x , y , z;
    	bool operator<(const data &a)const {return z < a.z;}
    }a[N];
    int f[N] , c[N];
    int find(int x)
    {
    	return x == f[x] ? x : f[x] = find(f[x]);
    }
    int main()
    {
    	int n , m , i , j , tx , ty;
    	long long ans = 0;
    	scanf("%d%d" , &n , &m);
    	for(i = 1 ; i <= n ; i ++ )
    		for(j = 1 ; j <= m ; j ++ )
    			scanf("%d" , &a[(i - 1) * m + j].z) , a[(i - 1) * m + j].x = i , a[(i - 1) * m + j].y = j + n;
    	sort(a + 1 , a + n * m + 1);
    	for(i = 1 ; i <= n + m ; i ++ ) f[i] = i;
    	for(i = 1 ; i <= n * m ; i ++ )
    	{
    		tx = find(a[i].x) , ty = find(a[i].y);
    		if(tx == ty && !c[tx]) c[tx] = 1 , ans += a[i].z;
    		if(tx != ty && !(c[tx] && c[ty])) f[tx] = ty , c[ty] |= c[tx] , ans += a[i].z;
    	}
    	printf("%lld
    " , ans);
    	return 0;
    }
    

     

  • 相关阅读:
    机房收费系统总结
    python手记(45)
    Hbase深入学习(二) 安装hbase
    Java异常机制
    MySQL 分析服务器状态
    人生感悟:人生像吃自助餐
    Android使用蓝牙连接adb调试App
    JQuery DataTables 列自己定义数据类型排序
    Android-自己定义图像资源的使用(1)
    11款开放中文分词引擎大比拼
  • 原文地址:https://www.cnblogs.com/GXZlegend/p/7493170.html
Copyright © 2011-2022 走看看