• Harry Potter and The Vector Spell-gym101669D(矩阵的秩-并查集)


    在这里插入图片描述
    Sample Input

    3 3 
    2 1 3 
    2 1 2 
    2 2 3 
    

    Sample Output
    2
    Sample Input 2

    4 3
    3 1 2 3 
    1 1
    1 2
    1 3
    

    在这里插入图片描述

    Sample Output 2
    3
    题意:
    给出一个0 1矩阵,这个矩阵中每一列有且只有两个1,求这个矩阵的秩
    输入一行中1的数量x,然后后面x个数代表1出现的列位置
    求出这个矩阵的秩

    方法:
    思维并查集
    将每一列的两个1所在的行编号连一条边,然后求一下最小生成树就好
    其实就是我们维护一个并查集,在这个并查集里面的所有点都可以两两组合形成一列,如果不在同一个集合里面,就会对答案+1

    int fa[maxn];
    int vis[maxn];
    int n,m;
    inline void init(){
        for(int i=0;i<maxn;i++) fa[i] = i,vis[i] = 0;
    }
    inline int findFa(int x){
        if(x == fa[x]) return x;
        else return fa[x] = findFa(fa[x]);
    }
    int ans = 0;
    inline void Union(int x,int y){
        int fax = findFa(x);
        int fay = findFa(y);
        if(fax == fay) return ;
        else{
            fa[fax] = fay;
            ans ++;
        }
    }
    vector<int> vet[maxn];
    int main() {
        cin >> m >> n;
        init();
        for(int i=1;i<=m;i++){
            int x=read;
            while(x --){
                int val; cin >>val;
                vet[val].push_back(i);
            }
        }
    
        for(int i=1;i<=n;i++){
            int x = vet[i][0];
            int y = vet[i][1];
            Union(x,y);
        }
        cout << ans << endl;
    	return 0;
    }
    
    int n, m;
    int fa[maxn];
    int vis[maxn];
    void init() {
        for (int i = 0; i < maxn; i++)
            fa[i] = i, vis[i] = 0;
    }
    inline int findFa(int x) {
        if (x == fa[x])
            return x;
        else
            return fa[x] = findFa(fa[x]);
    }
    inline void Union(int x, int y) {
        int fax = findFa(x);
        int fay = findFa(y);
        if (fax == fay)
            return;
        else {
            fa[fax] = fay;
        }
    }
    int main() {
        cin >> m >> n;
        init();
        for (int i = 1; i <= m; i++) {
            int x = read;
            for (int j = 1; j <= x; j++) {
                int t = read;
                if (vis[t])
                    Union(vis[t], i);
                else
                    vis[t] = i;
            }
        }
        int ans = 0;
        for (int i = 1; i <= m; i++) {
            if (i == fa[i])
                ans++;
        }
        cout << m - ans << endl;
        return 0;
    }
    
  • 相关阅读:
    带你正确的使用List的retainAll方法求交集
    Java URL
    如何正确的创建线程
    小贾漫谈——Java反射
    二、定时器的应用
    网络获取json数据并解析
    异步消息处理机制Handler
    手机安全卫士——Splash总结
    click事件触发也有失灵的时候?
    一张图看透微信公众号、企业号、小程序
  • 原文地址:https://www.cnblogs.com/PushyTao/p/15101026.html
Copyright © 2020-2023  润新知