SCL--二分匹配

2015-05-28 21:03:27

总结:

 

首先是跑得最快的 Hopcroft-Karp (这个算法是因为 hdu 2389 才学的..)

bool find(int p){
    for(int i = first[p]; ~i; i = e[i].next){
        int v = e[i].v;
        if(!vis[v] && dy[v] == dx[p] + 1){
            vis[v] = 1;
            if(!my[v] || find(my[v])){
                my[v] = p;
                mx[p] = v;
                return true;
            }
        }
    }
    return false;
}

int HK(){
    memset(mx,0,sizeof(mx));
    memset(my,0,sizeof(my));
    int res = 0;
    while(1){
        bool flag = false;
        while(!Q.empty()) Q.pop();
        memset(dx,0,sizeof(dx));
        memset(dy,0,sizeof(dy));
        for(int i = 1; i <= m; ++i) if(!mx[i]) Q.push(i);
        while(!Q.empty()){
            int x = Q.front(); Q.pop();
            for(int i = first[x]; ~i; i = e[i].next){
                int v = e[i].v;
                if(!dy[v]){
                    dy[v] = dx[x] + 1;
                    if(my[v]){
                        dx[my[v]] = dy[v] + 1;
                        Q.push(my[v]);
                    }
                    else flag = true;
                }
            }
        }
        if(!flag) break;
        memset(vis,0,sizeof(vis));
        for(int i = 1; i <= m; ++i)
            if(!mx[i] && find(i)) ++res;
    }
    return res;
}

 

接着是经典的 Hungary:

bool find(int p){
    for(int i = first[p]; ~i; i = e[i].next){
        int v = e[i].v;
        if(used[v] == 0){
            used[v] = 1;
            if(mat[v] == 0 || find(mat[v])){
                mat[v] = p;
                tmat[p] = v;
                return true;
            }
        }
    }
    return false;
}

int Hungary(){
    memset(mat,0,sizeof(mat));
    memset(tmat,0,sizeof(tmat));
    int res = 0;
    for(int i = 1; i <= N; ++i){
        memset(used,0,sizeof(used));
        if(find(i)) res++;
    }
    return res;
}
posted @ 2015-05-28 21:06  Naturain  阅读(148)  评论(0编辑  收藏  举报