图论——二分图匹配

来源:互联网 发布:linux项目实战 编辑:程序博客网 时间:2024/06/16 03:13

POJ NO.3041

该题换一种思路思考,将水平边,垂直边分别看做顶点,而把行星的坐标作为连接两顶点的边。如下图:


所以,我们可以用“二分匹配”解此题。代码如下:


#include<iostream>#include<cstring>#include<string>#include<cstdio>#include<algorithm>#include <vector>#include <queue>#define MAX 505*505int V;//顶点数int match[MAX];bool used[MAX];using namespace std;vector<int> G[MAX];int N;//N*Nint k;//K颗行星void add_edge(int u,int v);int bit_match();bool dfs(int v);int main() {    cin>>N>>k;    V = N*2-1;    while(k--) {        int x,y;        cin>>x>>y;        add_edge(x-1,N+y-1);}        cout <<bit_match();}void add_edge(int u,int v) {    G[u].push_back(v);    G[v].push_back(u);}//寻找增广路径bool dfs(int v) {    used[v] = true;    for(int i=0; i<G[v].size(); i++) {        int u = G[v][i],w = match[u];        if(w<0||!used[w] &&dfs(w)) {            match[v] = u;            match[u] = v;            return true;        }    }    return false;}int bit_match() {    int res = 0;    memset(match,-1,sizeof(match));    for(int v = 0; v<V; v++) {        if(match[v]<0) {            memset(used,0,sizeof(used));            if(dfs(v)) {                res++;            }        }    }    return res;}


poj 3020

看了一大牛的题解,总结了一下几点步骤:

1.将输入的地图中 ‘*’ 以递增数字的形式存储

2.确定相邻点之间的关系,进行拆点,并以矩阵的形式存储

3.求出 2 中矩阵的最大匹配

4.利用“无向二分图的最小路径覆盖 = 顶点数 - 最大二分匹配/2”


#include<iostream>#include<string.h>#include<fstream>using namespace std;const int MAXN = 42*12;int Amap[43][13] = {0};int h,w, star;bool point[MAXN][MAXN] = {0};int xM[MAXN*2], yM[MAXN*2]; // 输出量bool chk[MAXN*2]; // 辅助量检查某轮y[v] 是否被checkbool SearchPath(int u) { ////寻找增广路径    int v;    for(v = 1; v <= star; v++)        if(point[u][v] && !chk[v]) {            chk[v] = true;            if(yM[v] == -1 || SearchPath(yM[v])) {                yM[v] = u;                xM[u] = v;                return true ;            }        }    return false ;}int MaxMatch() {//第三步    int u, ret = 0 ;    memset(xM, -1, sizeof (xM));    memset(yM, -1, sizeof (yM));    for(u = 1; u <= star; u++)        if(xM[u] == -1) {            memset(chk, false, sizeof (chk));            if(SearchPath(u)) ret++;        }    return ret;}int main() {    int times = 0;    char temp_c[11];    cin>>times;    while(times --) {        memset(point,0,sizeof(point));        memset(Amap,0,sizeof(Amap));        star = 0;        cin>>h>>w;        for(int i = 0; i<h; i++) {//第一步            for(int j =0 ; j<w; j++) {                char temp ;                cin>>temp;                if(temp == '*')                    Amap[i][j] = ++star;                else                    Amap[i][j] = 0;            }        }        for(int i = 0; i<h; i++) {//构造point[]数组,即第二步            for(int j =0 ; j<w; j++) {                if(Amap[i][j] != 0) {                    if(i-1 >= 0 && Amap[i-1][j] != 0 ) {                        point [Amap[i][j]][Amap[i-1][j]] = true;                        point [Amap[i-1][j]][Amap[i][j]] = true;                    }                    if(i+1 < h && Amap[i+1][j] != 0 ) {                        point [Amap[i][j]][Amap[i+1][j]] = true;                        point [Amap[i+1][j]][Amap[i][j]] = true;                    }                    if(j-1 >= 0 && Amap[i][j-1] != 0 ) {                        point [Amap[i][j-1]][Amap[i][j]] = true;                        point [Amap[i][j]][Amap[i][j-1]] = true;                    }                    if(j+1 < w && Amap[i][j+1] != 0 ) {                        point [Amap[i][j]][Amap[i][j+1]] = true;                        point [Amap[i][j+1]][Amap[i][j]] = true;                    }                }            }        }        cout<<star - MaxMatch()/2<<endl;//第四部    }}

如有错误,还望指出

转载请注明出处:http://blog.csdn.net/big_heart_c



0 0