Swap HDU - 2819

//把矩阵按行和列缩点,格子为1的就在所在行列加边
//然后二分图求最大匹配,如果是n,代表可行,小于n就输出-1
#include<cstdio>
#include<cstring>
using namespace std;
typedef long long ll;
const int N=100+10;
int g[N][N];
int match[N];
bool used[N];
int n;
bool find(int u) {
    for(int i=1; i<=n; i++) {
        if(used[i]||!g[u][i]) continue;
        used[i]=true;
        if(match[i]==-1||find(match[i])) {
            match[i]=u;
            return true;
        }
    }
    return false;
}
int solve() {
    int res=0;
    memset(match,-1,sizeof match);
    for(int i=1; i<=n; i++) 
    {
        memset(used,false,sizeof(used));
        if(find(i)) 
            res++;
    }
    return res;
}
int a[N],b[N];
int main() {
    while(~scanf("%d",&n)) 
    {
        for(int i=1; i<=n; i++)
            for(int j=1; j<=n; j++)
                scanf("%d",&g[i][j]);
        int num=solve();
        if(num==n)
        {
            int m=0;
            for(int i=1; i<=n; i++) 
            {
                while(match[i]!=i) 
                {
                    a[m]=i;
                    b[m]=match[i];
                    m++;
                    int t=match[i];
                    match[i]=match[match[i]];
                    match[t]=t;
                }
            }
            printf("%d\n",m);
            for(int i=0; i<m; i++)
                printf("C %d %d\n",a[i],b[i]);
        } else 
            printf("-1\n");
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/QingyuYYYYY/p/12422680.html