zoukankan      html  css  js  c++  java
  • 消消乐

    链接:https://ac.nowcoder.com/acm/contest/216/D
    来源:牛客网

    r神在和小b比赛玩一个名为“消消乐”的游戏,在一个n*m的棋盘上,一些棋子分布在格点上,游戏玩家有一个名为超蓝光波的武器,可以消除一行或者一列的所有棋子,使用超蓝光波需要耗费一点能量,消除完所有的棋子之后,花费能量越少得分越高。
    r神为了超过排名第一的小b,夺得荣誉称号“天下第一”,他需要寻求你的帮助,他希望知道最少需要使用多少次“超蓝光波”,以及在哪行、哪列使用。

    输入描述:

    第一行两个正整数n(n<=2000),m(m<=2000);

    接下来n行,每行m个字符,表示棋盘,其中“.”表示该处没有棋子,“*”表示该处有棋子,棋子个数<=100000

    输出描述:

    第一行输出一个正整数,表示最少需要使用的“超蓝光波”次数

    第二行N+1个正整数,第一个数为N,表示需要消掉的行数,从小到大输出每个需要消除的行号

    第三行M+1个正整数,第一个数为M,表示需要消掉的列数,从小到大输出每个需要删除的列号

    如果有多种情况,任意输出一种即可。
    示例1

    输入

    复制
    3 4
    .*..
    **.*
    .*..

    输出

    复制
    2
    1 2
    1 2
    示例2

    输入

    复制
    3 4
    .*..
    **.*
    ..*.

    输出

    复制
    3
    3 1 2 3 
    0

    题意 : 每次可以消去一行或一列,问最小操作次数是多少 ?
    思路分析 :
      一个比较好想到的思路就是用行和列去创建一个二分图,就可以转换成一个最小顶点覆盖的问题了,在二分图中他的数量又等同于最大匹配数
      然后就是分别将两侧的独立点集找到,从左侧的所有未匹配的点出发,找可以到的所有的点,最后左侧所有未到的点和右侧所有可以到的点就是最小独立集了
    代码示例 :
      
    using namespace std;
    #define ll long long
    const int maxn = 1e6+5;
    const int mod = 1e9+7;
    const double eps = 1e-9;
    const double pi = acos(-1.0);
    const int inf = 0x3f3f3f3f;
    
    int n, m;
    char s[2005];
    vector<int>ve[2005];
    int le[2005]; int ri[2005]; // le为左边第i个点匹配的编号
                                // ri 为右边第i个点匹配的编号
    bool S[2005], T[2005];
    
    bool fid(int x){
        S[x] = true;
        for(int i = 0; i < ve[x].size(); i++){
            int to = ve[x][i];
            if (T[to]) continue;
            T[to] = true;
            if (ri[to] == 0 || fid(ri[to])) {
                ri[to] = x;
                le[x] = to;
                return true;
            }
        }
        return false;
    }
    
    vector<int>x, y; // 分别用来求 两侧的最小独立点集中的点
    void mincover() {
        memset(S, false, sizeof(S));
        memset(T, false, sizeof(T));
        for(int i = 1; i <= n; i++) {
            if (le[i] == 0) {
                fid(i);
            }
        }
        for(int i = 1; i <= n; i++){
            if (!S[i]) x.push_back(i);
        }
        for(int i = 1; i <= m; i++){
            if (T[i]) y.push_back(i);
        }
    }
    
    int main() {
        //freopen("in.txt", "r", stdin);
        //freopen("out.txt", "w", stdout);
        
        cin >> n >> m;
        for(int i = 1; i <= n; i++){
            scanf("%s", s+1);
            for(int j = 1; j <= m; j++){
                if (s[j] == '*') ve[i].push_back(j);
            }    
        }
        int ans = 0;
        for(int i = 1; i <= n; i++){
            memset(T, 0, sizeof(T));
            if (fid(i)) ans++;
        }
        printf("%d
    ", ans);
        mincover();
        printf("%d", x.size());
        for(int i = 0; i < x.size(); i++) printf(" %d", x[i]);
        puts("");
        printf("%d", y.size());
        for(int i = 0; i < y.size(); i++) printf(" %d", y[i]);
        puts("");
        return 0;
    }
    
    东北日出西边雨 道是无情却有情
  • 相关阅读:
    Java应用中的SQL依赖注入攻击和防范
    强大的 Jquery图表绘制插件 —— jqPlot
    jqPlot的Option配置对象详解
    也谈Java值传递到底传递了什么?
    Use Case 中 include 与 extend 的区别
    STAR UML 简述1
    在Hibernate中使用 HibernateTemplate的三种方法
    jquery ui tabs详解(中文)
    高性能网页开发规则
    如何绘制 UML 活动图(Activity Diagram)
  • 原文地址:https://www.cnblogs.com/ccut-ry/p/9900009.html
Copyright © 2011-2022 走看看