• HDU 2819 Swap (行列匹配+输出解)


    题意:是否能使对角线上全是1 ,这个简单直接按行列匹配。难在路径的输出,我们知道X,Y左右匹配完了之后,不一定是1–1,2–2,3–3……这种匹配。可能是1–3,2–1,3–2,我们要把他们交换成前一种的匹配形式,也就是路径的答案,再有矩阵的一些关于秩的性质。行变换和列变换是等价的。

    
    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<cmath>
    #include<set>
    #include<map>
    #include<string>
    #include<cstring>
    #include<stack>
    #include<queue>
    #include<vector>
    #include<cstdlib>
    #define lson (rt<<1),L,M
    #define rson (rt<<1|1),M+1,R
    #define M ((L+R)>>1)
    #define cl(a,b) memset(a,b,sizeof(a));
    #define LL long long
    #define P pair<int,int>
    #define X first
    #define Y second
    #define pb push_back
    #define fread(zcc)  freopen(zcc,"r",stdin)
    #define fwrite(zcc) freopen(zcc,"w",stdout)
    using namespace std;
    const int maxn=105;
    const int inf=999999;
    
    vector<int> G[maxn];
    int matching[maxn];
    bool vis[maxn];
    int Nx;
    int dfs(int u){
        int N=G[u].size();
        for(int i=0;i<N;i++){
            int v=G[u][i];
            if(vis[v])continue;
            vis[v]=true;
            if(matching[v]==-1||dfs(matching[v])){
                matching[v]=u;
                return 1;
            }
        }
        return 0;
    }
    int hungar(){
        int ans=0;
        cl(matching,-1);
        for(int i=0;i<Nx;i++){
            cl(vis,false);
            ans+=dfs(i);
        }
        return ans;
    }
    int Left[maxn],Right[maxn];
    int main(){
    
        int n;
        while(~scanf("%d",&n)){
            for(int i=0;i<maxn;i++)G[i].clear();
            for(int i=0;i<n;i++){
                for(int j=0;j<n;j++){
                    int x;
                    scanf("%d",&x);
                    if(x)G[i].pb(j);
                }
            }
            Nx=n;
            int ans=hungar();
            if(ans<n){
                puts("-1");
                continue;
            }
    
            int num=0;
            for(int i=0;i<n;i++){//查找路径
                int j;
                for(j=i;j<n;j++)if(matching[j]==i)break;
                if(i!=j){
                    Left[num]=i;Right[num++]=j;
                    swap(matching[i],matching[j]);
                }
            }
            printf("%d
    ",num);
            for(int i=0;i<num;i++){
                printf("C %d %d
    ",Left[i]+1,Right[i]+1);
            }
        }
        return 0;
    }
    
    
    
    
    
  • 相关阅读:
    vue中使用AES.js和crypto.js加密
    vue项目中使用日期获取今日,昨日,上周,下周,上个月,下个月的数据
    vue项目中的路由守卫
    vue中携带token以及发送ajax
    vue项目中的字符串每隔4位一个空格
    vue中Echarts的使用-自选效果
    平衡树——Treap
    2021牛客寒假算法训练营3题解(9/10)
    2021牛客寒假算法训练营1题解(9/10)
    模板、知识点积累
  • 原文地址:https://www.cnblogs.com/clnchanpin/p/7265858.html
Copyright © 2020-2023  润新知