zoukankan      html  css  js  c++  java
  • HDU 2819 Swap(行列式性质+最大匹配)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2819

    题目大意:给你一个n*n的01矩阵,问是否可以通过任意交换整行或者整列使得正对角线上都是1。

    解题思路:

    按行列建图,求最大匹配,若最大匹配数<n,则肯定无解(矩阵的秩要等于n才有解)。
    若有解,则肯定可以通过只交换行或者交换列得到。所以我们从i=1 to n检查link[i]=i(link[i]表示第i列的1对应的行号)是否成立,
    否则找到link[j]=i交换link[i]和link[j]并记录下交换步骤。

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<vector>
    #include<algorithm>
    using namespace std;
    const int N=1e3+5;
    
    int n;
    int link[N];
    bool vis[N];
    vector<int>v[N];
    struct node{
        int x,y;
        node(int x,int y):x(x),y(y){}
    };
    
    bool dfs(int u){
        for(int i=0;i<v[u].size();i++){
            int t=v[u][i];
            if(!vis[t]){
                vis[t]=true;
                if(link[t]==-1||dfs(link[t])){
                    link[t]=u;
                    return true;
                }
            }
        }
        return false;
    }
    
    int max_match(){
        memset(link,-1,sizeof(link));
        int ans=0;
        for(int i=1;i<=n;i++){
            memset(vis,false,sizeof(vis));
            if(dfs(i)) ans++;
        }
        return ans;
    }
    
    int main(){
        while(~scanf("%d",&n)){
            for(int i=1;i<=n;i++) v[i].clear();
            for(int i=1;i<=n;i++){
                for(int j=1;j<=n;j++){
                    int x;
                    scanf("%d",&x);
                    if(x) v[i].push_back(j);
                }
            }
            if(max_match()<n)
                puts("-1");
            else{
                vector<node>ans;
                for(int i=1;i<=n;i++){
                    //若link[i]!=i则找到对应的link[j]==i与之交换,满足link[i]=i
                    if(link[i]!=i){
                        for(int j=1;j<=n;j++){
                            if(link[j]==i){
                                swap(link[i],link[j]);
                                ans.push_back(node(i,j));
                            }
                        }
                    }
                }
                printf("%d
    ",ans.size());
                for(int i=0;i<ans.size();i++){
                    printf("C %d %d
    ",ans[i].x,ans[i].y);
                }
            }
        }
        return 0;
    }
  • 相关阅读:
    如何在markdown隐藏代码块
    html基础
    驻留机制
    字典
    echarts简单使用
    selenium的基本操作
    Excel上传、下载、models 自定义字段、批量执行(可选)
    django之自定义标签(路径url反向解码)
    邮件自动生成发送用例报告
    前台获取后台保存的数据
  • 原文地址:https://www.cnblogs.com/fu3638/p/8785379.html
Copyright © 2011-2022 走看看