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

来源:互联网 发布:免费伴奏软件 编辑:程序博客网 时间:2024/05/04 16:56

题意:能否使对角线上全是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\n",num);        for(int i=0;i<num;i++){            printf("C %d %d\n",Left[i]+1,Right[i]+1);        }    }    return 0;}
0 0
原创粉丝点击