zoukankan      html  css  js  c++  java
  • POJ 1325 Machine Schedule(最小点覆盖)

    题目链接

    解题思路

      对原图做预处理,给横向的连通块和纵向的连通块编号,那么对于这个连通块内的点就有两个选择(x,y),这个点只有被其中一个覆盖就能被覆盖。所以结果就是求所有x->y的最大匹配,为什么呢?假设有一条边x_i -> x_j,如果两点不能匹配,说明其中一个已经匹配上了,根据前面所说的,只要被两个点中的一个覆盖就能覆盖一个点。假设两点能匹配,那么就说明有的点没有被覆盖,所以要求最大匹配。

    代码

    const int maxn = 1e2+10;
    const int maxm = 1e4+10;
    int r, c, x, y, nx[maxn][maxn], ny[maxn][maxn];
    int mp[3000][3000], vis[maxm], match[maxm]; 
    char g[maxn][maxn];
    int find(int xx) {
    	for (int i = 1; i<=y; ++i) 
    		if (mp[xx][i] && !vis[i]) {
    			vis[i] = true;
    			if (!match[i] || find(match[i])) {
    				match[i] = xx; return 1;
    			}
    		}
    	return 0;
    }
    int main() {
    	cin >> r >> c;
    	for (int i = 1; i<=r; ++i) scanf("%s", g[i]+1);
    	for (int i = 1; i<=r; ++i)
    		for (int j = 1; j<=c; ++j) 
    			if (g[i][j]=='*') {
    				++x;
    				while(g[i][j]=='*') {
    					nx[i][j] = x; ++j; 
    					//这里会跳过一个点,不过那个肯定不是结尾就是'.',不影响
    				} 
    			}
    	for (int i = 1; i<=c; ++i)
    		for (int j = 1; j<=r; ++j) 
    			if (g[j][i]=='*') {
    				++y;
    				while(g[j][i]=='*') {
    					ny[j][i] = y; ++j;
    					//这里会跳过一个点,不过那个肯定不是结尾就是'.',不影响
    				}
    			}
    	for (int i = 1; i<=r; ++i)
    		for (int j = 1; j<=c; ++j)
    			if (g[i][j]=='*') mp[nx[i][j]][ny[i][j]] = 1;
    	int ans = 0;
    	for (int i = 1; i<=x; ++i) {
    		zero(vis);
    		if (find(i)) ++ans;
    	}
    	cout << ans << endl;
        return 0;
    }
    
  • 相关阅读:
    HTML5文件上传前本地预览
    sql(2) DISTINCT
    sql (1)
    delphi 第4课
    delphi 第3课
    Delphi 第2课
    delphi 用户可以点击格式修改进行模板修改
    delphi 流程单打印
    Delphi 第一课
    【BZOJ4530】[Bjoi2014]大融合 LCT维护子树信息
  • 原文地址:https://www.cnblogs.com/shuitiangong/p/13526919.html
Copyright © 2011-2022 走看看