misschuer

常用链接

统计

积分与排名

百事通

最新评论

hdu 2819 Swap

//做这道题很郁闷, 一开始以为计算行列式值为1.怎么做都不对. 后来发现只需要斜线都为1即可.
//就会想到二分图的完全匹配

#include <iostream>
#include <queue>
#define MAXN 105
using namespace std;

typedef struct {
    
    int u, v;
}change;

int n;
int re[MAXN][MAXN];
bool chk[MAXN];
int match[MAXN];


int find (int x) {
   
    int i;
    for (i = 1;i <= n;++ i) {
       
        if (re[ x ][ i ] && !chk[ i ]) {
            //若x与i相连,且i不在增广路上             
            chk[ i ] = true;
            if (!match[ i ] || find(match[ i ])) {
                //若i还没有匹配,或从i的匹配项有增广路
                match[ i ] = x;
                return 1;
            }  
        }
    }  
   
    return 0;
}

void init() {

    memset(match , 0 , sizeof(match));
}

bool res() {
   
    int i, j, m, k, t;
   
    for(i = 1; i <= n; ++ i) {
       
        for(j = 1; j <= n; ++ j) {
           
            scanf("%d", &re[ i ][ j ]);
        }
    }       
   
    init();
    for (i = 1;i <= n;++ i) {          
       
        memset(chk , 0 , sizeof(chk));
        if (!find(i)) return false;
    }
   
    queue<change> Q;
    change p;
   
    for (j = 1; j <= n; ++ j) {
       
        m = j;
        for (k = j; k <= n; ++ k) if (match[ k ] <= match[ m ]) m = k;

        if (m != j) {
           
            p.u = m; p.v = j;
            Q.push(p);
            t = match[ m ];
            match[ m ] = match[ j ];
            match[ j ] = t;
        }
    }
   
    printf("%d\n", Q.size());
   
    while(!Q.empty()) {
       
        p = Q.front();
        Q.pop();
        printf("C %d %d\n", p.u, p.v);
    }
    return true;
}

int main() {
   
    while (~scanf("%d", &n)) {
       
        if(!res()) puts("-1"); 
    }    
    return 0;
}

 

posted on 2011-03-19 20:03 此最相思 阅读(338) 评论(0)  编辑 收藏 引用


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理